zena 0.15.2 → 0.16.0
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/.gitignore +20 -0
- data/CREDITS +27 -0
- data/Capfile +3 -0
- data/DEVELOPERS +46 -0
- data/History.txt +15 -0
- data/MIT-LICENSE +19 -0
- data/Rakefile +44 -0
- data/TODO +24 -0
- data/TODO_ZENA_1_0 +23 -0
- data/app/controllers/application_controller.rb +3 -0
- data/app/controllers/documents_controller.rb +22 -56
- data/app/controllers/nodes_controller.rb +42 -27
- data/app/controllers/pings_controller.rb +19 -0
- data/app/controllers/relations_controller.rb +5 -1
- data/app/controllers/sites_controller.rb +1 -46
- data/app/controllers/user_sessions_controller.rb +47 -0
- data/app/controllers/users_controller.rb +1 -0
- data/app/controllers/versions_controller.rb +25 -7
- data/app/controllers/virtual_classes_controller.rb +1 -1
- data/app/helpers/application_helper.rb +1 -1
- data/app/models/comment.rb +2 -1
- data/app/models/contact_content.rb +2 -2
- data/app/models/data_entry.rb +5 -6
- data/app/models/document.rb +14 -10
- data/app/models/document_content.rb +4 -6
- data/app/models/iformat.rb +2 -2
- data/app/models/image_content.rb +6 -9
- data/app/models/node.rb +106 -164
- data/app/models/page.rb +0 -20
- data/app/models/site.rb +42 -12
- data/app/models/template.rb +3 -8
- data/app/models/template_content.rb +2 -0
- data/app/models/text_document.rb +13 -8
- data/app/models/user.rb +47 -100
- data/app/models/user_session.rb +4 -0
- data/app/models/version.rb +1 -1
- data/app/views/comments/create.rjs +3 -3
- data/app/views/comments/edit.rjs +1 -1
- data/app/views/comments/update.rjs +1 -1
- data/app/views/nodes/_import_results.rhtml +1 -1
- data/app/views/nodes/create.rjs +3 -3
- data/app/views/templates/document_create_tabs/_file.rhtml +1 -2
- data/app/views/templates/document_create_tabs/_import.rhtml +7 -2
- data/app/views/templates/edit_tabs/_document.rhtml +1 -3
- data/app/views/templates/edit_tabs/_image.rhtml +1 -3
- data/app/views/versions/_tr.rhtml +1 -1
- data/app/views/versions/edit.rhtml +2 -26
- data/bin/zena +6 -1
- data/bricks/delayed_job/README +18 -0
- data/bricks/delayed_job/migrate/20091104191643_create_delayed_jobs_table.rb +19 -0
- data/bricks/delayed_job/misc/init.rb +8 -0
- data/bricks/delayed_job/misc/tasks.rb +2 -0
- data/bricks/math/patch/application_helper.rb +1 -1
- data/bricks/sphinx/MIT-LICENSE +19 -0
- data/bricks/sphinx/README +19 -0
- data/bricks/sphinx/lib/use_sphinx.rb +78 -0
- data/bricks/sphinx/migrate/20091102171258_add_delta_for_sphinx.rb +9 -0
- data/bricks/sphinx/misc/deploy.rb +20 -0
- data/bricks/sphinx/misc/sphinx.yml +12 -0
- data/bricks/sphinx/misc/tasks.rb +21 -0
- data/bricks/sphinx/patch/node.rb +8 -0
- data/bricks/tags/lib/has_tags.rb +5 -3
- data/bricks/tags/test/zafu/tags.yml +13 -1
- data/config/bricks.yml +35 -0
- data/config/deploy.rb +8 -1
- data/config/environment.rb +1 -1
- data/config/environments/production.rb +1 -1
- data/config/gems.yml +28 -5
- data/config/sphinx.yml +12 -0
- data/db/init/base/skins/default/Node-+popupLayout.zafu +1 -16
- data/db/migrate/20091026161708_add_persistence_token.rb +13 -0
- data/db/migrate/20091101184952_add_session_table.rb +16 -0
- data/db/migrate/20091123175137_add_single_access_token.rb +9 -0
- data/db/migrate/20091124161608_rebuild_fullpath.rb +11 -0
- data/db/schema.rb +21 -8
- data/doc/README_FOR_APP +24 -0
- data/doc/fixtures.graffle +19568 -0
- data/doc/fixtures.pdf +0 -0
- data/doc/template/LICENSE +184 -0
- data/doc/template/README +37 -0
- data/doc/template/allison.css +283 -0
- data/doc/template/allison.js +307 -0
- data/doc/template/allison.rb +260 -0
- data/doc/template/cache/BODY +588 -0
- data/doc/template/cache/CLASS_INDEX +4 -0
- data/doc/template/cache/CLASS_PAGE +1 -0
- data/doc/template/cache/FILE_INDEX +4 -0
- data/doc/template/cache/FILE_PAGE +1 -0
- data/doc/template/cache/FONTS +1 -0
- data/doc/template/cache/FR_INDEX_BODY +1 -0
- data/doc/template/cache/IMGPATH +1 -0
- data/doc/template/cache/INDEX +1 -0
- data/doc/template/cache/JAVASCRIPT +307 -0
- data/doc/template/cache/METHOD_INDEX +4 -0
- data/doc/template/cache/METHOD_LIST +1 -0
- data/doc/template/cache/SRC_PAGE +1 -0
- data/doc/template/cache/STYLE +283 -0
- data/doc/template/cache/URL +1 -0
- data/doc/zafu_changes.yml +29 -0
- data/lib/base_additions.rb +1 -1
- data/lib/bricks.rb +9 -0
- data/lib/bricks/loader.rb +86 -0
- data/lib/bricks/requirements_validation.rb +71 -0
- data/lib/tasks/zena.rake +42 -4
- data/lib/zafu/action.rb +285 -0
- data/lib/zafu/ajax.rb +93 -0
- data/lib/zafu/attributes.rb +117 -0
- data/lib/zafu/calendar.rb +159 -0
- data/lib/zafu/context.rb +330 -0
- data/lib/zafu/core/html.rb +102 -0
- data/lib/zafu/core/move_to_parser.rb +167 -0
- data/lib/zafu/dates.rb +58 -0
- data/lib/zafu/display.rb +502 -0
- data/lib/zafu/eval.rb +66 -0
- data/lib/zafu/experimental.rb +66 -0
- data/lib/zafu/i18n.rb +64 -0
- data/lib/zafu/meta.rb +25 -0
- data/lib/zafu/refactor.rb +73 -0
- data/lib/zafu/support/context.rb +265 -0
- data/lib/zafu/support/dom.rb +145 -0
- data/lib/zafu/support/erb.rb +62 -0
- data/lib/zafu/support/flow.rb +401 -0
- data/lib/zafu/support/forms.rb +461 -0
- data/lib/zafu/support/links.rb +306 -0
- data/lib/zafu_parser.rb +26 -2
- data/lib/zena.rb +34 -15
- data/lib/zena/acts/multiversion.rb +2 -2
- data/lib/zena/acts/secure.rb +41 -30
- data/lib/zena/app.rb +7 -10
- data/lib/zena/controller/test_case.rb +12 -7
- data/lib/zena/crypto_provider/initial.rb +15 -0
- data/lib/zena/db.rb +6 -1
- data/lib/zena/deploy.rb +34 -6
- data/lib/zena/deploy/logrotate_app.rhtml +9 -0
- data/lib/zena/deploy/logrotate_host.rhtml +34 -0
- data/lib/zena/deploy/template.rb +1 -9
- data/lib/zena/foxy_parser.rb +1 -1
- data/lib/zena/info.rb +3 -1
- data/lib/zena/migrator.rb +1 -1
- data/lib/zena/parser.rb +12 -4
- data/lib/zena/parser/zazen_rules.rb +6 -6
- data/lib/zena/parser/zena_rules.rb +1 -7
- data/lib/zena/routes.rb +5 -5
- data/lib/zena/test_controller.rb +7 -2
- data/lib/zena/unit/test_case.rb +6 -8
- data/lib/zena/use/ajax.rb +10 -10
- data/lib/zena/use/authlogic.rb +93 -0
- data/lib/zena/use/dyn_attributes.rb +5 -0
- data/lib/zena/use/html_tags.rb +16 -34
- data/lib/zena/use/i18n.rb +4 -1
- data/lib/zena/use/node_query_finders.rb +8 -4
- data/lib/zena/use/refactor.rb +8 -20
- data/lib/zena/use/relations.rb +1 -0
- data/lib/zena/use/rendering.rb +4 -2
- data/lib/zena/use/search.rb +52 -0
- data/lib/zena/use/test_helper.rb +27 -28
- data/lib/zena/use/upload.rb +188 -0
- data/lib/zena/use/urls.rb +16 -14
- data/lib/zena/use/zafu.rb +16 -63
- data/lib/zena/use/zazen.rb +8 -8
- data/lib/zena/view/test_case.rb +8 -4
- data/locale/en/LC_MESSAGES/zena.mo +0 -0
- data/locale/en/zena.po +3 -3
- data/public/.htaccess +40 -0
- data/public/javascripts/upload-progress.js +17 -8
- data/public/javascripts/zena.js +8 -2
- data/public/stylesheets/popup.css +1 -0
- data/script/about +3 -0
- data/script/apache_logging +25 -0
- data/script/breakpointer +3 -0
- data/script/console +3 -0
- data/script/dbconsole +3 -0
- data/script/destroy +3 -0
- data/script/generate +3 -0
- data/script/performance/benchmarker +3 -0
- data/script/performance/profiler +3 -0
- data/script/plugin +3 -0
- data/script/process/inspector +3 -0
- data/script/process/reaper +3 -0
- data/script/process/spawner +3 -0
- data/script/runner +3 -0
- data/script/server +3 -0
- data/script/set_revision +29 -0
- data/spec/controllers/versions_controller_spec.rb +11 -0
- data/test/fixtures/files/Node-test.zafu +1 -1
- data/test/functional/nodes_controller_test.rb +25 -0
- data/test/functional/pings_controller_test.rb +8 -0
- data/test/functional/user_sessions_controller_test.rb +59 -0
- data/test/functional/users_controller_test.rb +81 -19
- data/test/helpers/node_query/filters.yml +5 -0
- data/test/helpers/node_query_test.rb +3 -3
- data/test/integration/multiple_hosts_test.rb +1 -1
- data/test/integration/navigation_test.rb +1 -1
- data/test/sites/complex/users.yml +1 -1
- data/test/sites/ocean/users.yml +3 -3
- data/test/sites/zena/users.yml +5 -4
- data/test/test_zena.rb +38 -38
- data/test/unit/cached_page_test.rb +2 -2
- data/test/unit/comment_test.rb +0 -1
- data/test/unit/document_test.rb +23 -11
- data/test/unit/helpers/ping_helper_test.rb +4 -0
- data/test/unit/multiversion_test.rb +24 -16
- data/test/unit/node_test.rb +32 -93
- data/test/unit/note_test.rb +9 -0
- data/test/unit/page_test.rb +2 -2
- data/test/unit/secure_test.rb +2 -12
- data/test/unit/site_test.rb +43 -24
- data/test/unit/template_test.rb +45 -3
- data/test/unit/text_document_test.rb +4 -3
- data/test/unit/user_test.rb +13 -33
- data/test/unit/zena/db_test.rb +8 -0
- data/test/unit/zena/parser/zazen.yml +4 -4
- data/test/unit/zena/use/dates_view_methods_test.rb +2 -1
- data/test/unit/zena/use/html_tags_test.rb +12 -4
- data/test/unit/zena/use/refactor_test.rb +4 -3
- data/test/unit/zena/use/rendering_test.rb +1 -0
- data/test/unit/zena/use/upload_test.rb +76 -0
- data/test/unit/zena/use/urls_test.rb +4 -0
- data/test/unit/zena/use/zafu_test.rb +8 -0
- data/test/unit/zena/workflow/status_version_test.rb +6 -0
- data/test/unit/zena/zena_tags/ajax.yml +4 -4
- data/test/unit/zena/zena_tags/basic.yml +21 -10
- data/test/unit/zena/zena_tags/relations.yml +0 -6
- data/test/unit/zena/zena_tags/rubyless.yml +35 -0
- data/test/unit/zena/zena_tags/zazen.yml +4 -4
- data/test/unit/zena/zena_tags_test.rb +36 -4
- data/vendor/TextMate/Zena.tmbundle/Commands/Run all yaml tests.tmCommand +1 -1
- data/vendor/TextMate/Zena.tmbundle/Commands/Run focused yaml test.tmCommand +2 -3
- data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/catch_exception.rb +39 -0
- data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/run_script.rb +102 -58
- data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/stdin_dialog.rb +14 -0
- data/vendor/TextMate/Zena.tmbundle/info.plist +2 -0
- data/zena.gemspec +2085 -0
- metadata +265 -90
- data/app/controllers/sessions_controller.rb +0 -41
- data/app/views/sites/zena_up.html.erb +0 -11
- data/config/database.yml +0 -40
- data/db/production.sqlite3 +0 -0
- data/lib/bricks/patcher.rb +0 -68
- data/lib/zena/parser/zena_tags.rb +0 -3562
- data/lib/zena/use/authentification.rb +0 -120
- data/public/images/ext/contact_pv.png +0 -0
- data/public/images/ext/other_pv.png +0 -0
- data/public/images/ext/page_pv.png +0 -0
- data/public/images/ext/page_tiny.png +0 -0
- data/public/images/ext/pdf_pv.png +0 -0
- data/public/images/ext/post_pv.png +0 -0
- data/public/images/ext/post_tiny.png +0 -0
- data/public/images/ext/project_pv.png +0 -0
- data/public/images/ext/project_tiny.png +0 -0
- data/public/images/ext/tag_pv.png +0 -0
- data/public/images/ext/zip_pv.png +0 -0
- data/tasks/ann.rake +0 -80
- data/tasks/bones.rake +0 -20
- data/tasks/gem.rake +0 -201
- data/tasks/git.rake +0 -40
- data/tasks/notes.rake +0 -27
- data/tasks/post_load.rake +0 -34
- data/tasks/rdoc.rake +0 -51
- data/tasks/rubyforge.rake +0 -55
- data/tasks/setup.rb +0 -292
- data/tasks/spec.rake +0 -54
- data/tasks/svn.rake +0 -47
- data/tasks/test.rake +0 -40
- data/tasks/zentest.rake +0 -36
- data/test/fixtures/comments.yml +0 -126
- data/test/fixtures/contact_contents.yml +0 -132
- data/test/fixtures/data_entries.yml +0 -65
- data/test/fixtures/discussions.yml +0 -48
- data/test/fixtures/document_contents.yml +0 -108
- data/test/fixtures/dyn_attributes.yml +0 -66
- data/test/fixtures/groups.yml +0 -86
- data/test/fixtures/groups_users.yml +0 -81
- data/test/fixtures/iformats.yml +0 -29
- data/test/fixtures/links.yml +0 -313
- data/test/fixtures/nodes.yml +0 -2592
- data/test/fixtures/relations.yml +0 -126
- data/test/fixtures/sites.yml +0 -58
- data/test/fixtures/template_contents.yml +0 -172
- data/test/fixtures/users.yml +0 -167
- data/test/fixtures/versions.yml +0 -1911
- data/test/fixtures/virtual_classes.yml +0 -87
- data/test/fixtures/zips.yml +0 -15
- data/test/functional/sessions_controller_test.rb +0 -73
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
=begin rdoc
|
|
2
|
-
Create, destroy sessions by letting users login and logout. When the user does not login, he/she is considered to be the anonymous user.
|
|
3
|
-
=end
|
|
4
|
-
class SessionsController < ApplicationController
|
|
5
|
-
skip_before_filter :authorize
|
|
6
|
-
|
|
7
|
-
def new
|
|
8
|
-
respond_to do |format|
|
|
9
|
-
format.html do
|
|
10
|
-
@node = visitor.site.root_node
|
|
11
|
-
render_and_cache :mode => '+login'
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def create
|
|
17
|
-
if user = User.login(params[:login], params[:password], request.host)
|
|
18
|
-
successful_login(user)
|
|
19
|
-
else
|
|
20
|
-
failed_login _("Invalid login or password.")
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
# Clears session information and redirects to home page.
|
|
25
|
-
def destroy
|
|
26
|
-
reset_session
|
|
27
|
-
if request.referer =~ %r{(http://#{visitor.site.host}:\d*/)#{AUTHENTICATED_PREFIX}(.*)}
|
|
28
|
-
redirect_to $1 + visitor.lang + $2
|
|
29
|
-
else
|
|
30
|
-
redirect_to :controller => 'nodes', :action => 'index', :prefix => visitor.lang
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
protected
|
|
35
|
-
|
|
36
|
-
def failed_login(message)
|
|
37
|
-
session[:user] = nil
|
|
38
|
-
flash[:error] = message
|
|
39
|
-
redirect_to '/login'
|
|
40
|
-
end
|
|
41
|
-
end
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
<% if @state == :wait -%>
|
|
2
|
-
<h2><%= _('Updating...') %></h2>
|
|
3
|
-
<p><%= _('Please wait while the code is updated and the site restarts (page reloads every 30s).') %></p>
|
|
4
|
-
<% elsif @state == :done -%>
|
|
5
|
-
<h2><%= _('Up to date') %></h2>
|
|
6
|
-
<p><%= _('Your site is running the latest version of zena.') %> (<%= Zena::VERSION %> r<%= @target_rev %>)</p>
|
|
7
|
-
<% else -%>
|
|
8
|
-
<h2><%= _('Update') %></h2>
|
|
9
|
-
<p><%= sprintf(_('Your site is running rev %i, newest revision is %i.'), @current_rev, @target_rev) %></p>
|
|
10
|
-
<p><%= link_to(_('Update'), :action => 'zena_up', :run => 'start', :rev => @target_rev) %></p>
|
|
11
|
-
<% end -%>
|
data/config/database.yml
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# Enter database configuration information here (rename this file "database.yml").
|
|
2
|
-
# You do not need to do any of this if you use capistraon (see config/deploy.rg).
|
|
3
|
-
# MySQL
|
|
4
|
-
login: &dev_login
|
|
5
|
-
adapter: mysql
|
|
6
|
-
socket: /tmp/mysql.sock
|
|
7
|
-
username: root
|
|
8
|
-
password:
|
|
9
|
-
|
|
10
|
-
development:
|
|
11
|
-
database: zena_dev
|
|
12
|
-
encoding: utf8
|
|
13
|
-
<<: *dev_login
|
|
14
|
-
|
|
15
|
-
# Warning: The database defined as "test" will be erased and
|
|
16
|
-
# re-generated from your development database when you run "rake".
|
|
17
|
-
# Do not set this db to the same as development or production.
|
|
18
|
-
test:
|
|
19
|
-
database: zena_test
|
|
20
|
-
encoding: utf8
|
|
21
|
-
<<: *dev_login
|
|
22
|
-
|
|
23
|
-
# FIXME: use in memory sqlite3 for testing
|
|
24
|
-
#test:
|
|
25
|
-
# adapter: sqlite3
|
|
26
|
-
# database: db/test.sqlite3
|
|
27
|
-
# pool: 5
|
|
28
|
-
# timeout: 5000
|
|
29
|
-
#
|
|
30
|
-
production:
|
|
31
|
-
database: zena_dev
|
|
32
|
-
encoding: utf8
|
|
33
|
-
<<: *dev_login
|
|
34
|
-
|
|
35
|
-
#production:
|
|
36
|
-
# adapter: sqlite3
|
|
37
|
-
# database: db/production.sqlite3
|
|
38
|
-
# pool: 5
|
|
39
|
-
# timeout: 5000
|
|
40
|
-
#
|
data/db/production.sqlite3
DELETED
|
Binary file
|
data/lib/bricks/patcher.rb
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
module Bricks
|
|
2
|
-
class Patcher
|
|
3
|
-
class << self
|
|
4
|
-
def bricks_folders
|
|
5
|
-
@bricks_folders ||= [File.join(Zena::ROOT, 'bricks'), File.join(RAILS_ROOT, 'bricks')].uniq.reject {|f| !File.exist?(f)}
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def models_paths
|
|
9
|
-
bricks_folders.map {|f| Dir["#{f}/**/models"] }.flatten
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def libs_paths
|
|
13
|
-
bricks_folders.map {|f| Dir["#{f}/**/lib"] }.flatten
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def foreach_brick(&block)
|
|
17
|
-
bricks_folders.each do |bricks_folder|
|
|
18
|
-
next unless File.exist?(bricks_folder)
|
|
19
|
-
Dir.entries(bricks_folder).sort.each do |brick|
|
|
20
|
-
next if brick =~ /\A\./
|
|
21
|
-
block.call(File.join(bricks_folder, brick))
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def apply_patches(file_name = nil)
|
|
27
|
-
file_name ||= caller[0].split('/').last.split(':').first
|
|
28
|
-
foreach_brick do |brick_path|
|
|
29
|
-
patch_file = File.join(brick_path, 'patch', file_name)
|
|
30
|
-
if File.exist?(patch_file)
|
|
31
|
-
load patch_file
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def load_bricks
|
|
37
|
-
# load all libraries in bricks
|
|
38
|
-
libs_paths.each do |lib_path|
|
|
39
|
-
Dir.foreach(lib_path) do |f|
|
|
40
|
-
next unless f =~ /\A.+\.rb\Z/
|
|
41
|
-
require File.join(lib_path, f)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# FIXME: do we really need to load these now, load_path isn't enough ?
|
|
46
|
-
models_paths.each do |models_path|
|
|
47
|
-
Dir.foreach(models_path) do |f|
|
|
48
|
-
next unless f =~ /\A.+\.rb\Z/
|
|
49
|
-
require File.join(models_path, f)
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def load_zafu(mod)
|
|
55
|
-
foreach_brick do |brick_path|
|
|
56
|
-
brick_name = File.basename(brick_path)
|
|
57
|
-
zafu_path = File.join(brick_path, 'zafu')
|
|
58
|
-
next unless File.exist?(zafu_path)
|
|
59
|
-
Dir.foreach(zafu_path) do |rules_name|
|
|
60
|
-
next if rules_name =~ /\A\./
|
|
61
|
-
load File.join(zafu_path, rules_name)
|
|
62
|
-
end
|
|
63
|
-
mod.send(:include, eval("Bricks::#{brick_name.capitalize}::Zafu"))
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
@@ -1,3562 +0,0 @@
|
|
|
1
|
-
=begin
|
|
2
|
-
Thoughts for ajax related stuff cleanup (dom_id, erb_dom_id, ...)
|
|
3
|
-
|
|
4
|
-
When we open a list context:
|
|
5
|
-
- we change the context_dom_id => unique name => "page"
|
|
6
|
-
|
|
7
|
-
When we open a single context (do_var, each, block):
|
|
8
|
-
- we change the context_dom_id => unique name with id => "page_{parent_id}"
|
|
9
|
-
|
|
10
|
-
Any 'id' is set with:
|
|
11
|
-
- "{context_dom_id}_{id}" => 'page_34' (if not in list) or 'page_12_34' if in list.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
List in list (initial node zip = 12):
|
|
15
|
-
context_dom_id dom_id (context_erb_dom_id, erb_dom_id)
|
|
16
|
-
<ul> page_12 page_12 [pages in='site'] new unique name
|
|
17
|
-
<li id='page_12_13'> page_12 page_12_13 [each] expand_with(:context_dom_id => 'page_13')
|
|
18
|
-
<ul> page_13
|
|
19
|
-
<li id='page_13_23'/> page_13 page_13_23 [each]
|
|
20
|
-
<li id='page_13_24'/> page_13 page_13_24 [each]
|
|
21
|
-
<li id='page_13_25'/> page_13 page_13_25 [each]
|
|
22
|
-
</ul>
|
|
23
|
-
</li>
|
|
24
|
-
<li id='page_12_14'> page_12 page_12_14 [each] expand_with(:context_dom_id => 'page_14')
|
|
25
|
-
<ul>
|
|
26
|
-
<li id='page_14_23'/> page_14 page_14_23 [each] expand_with(:context_dom_id => 'page_23')
|
|
27
|
-
<li id='page_14_27'/> page_14 page_14_27 [each] ...
|
|
28
|
-
</ul>
|
|
29
|
-
</li>
|
|
30
|
-
</ul>
|
|
31
|
-
|
|
32
|
-
<div id='page1_12'> page1_12 page1_12 [block] new unique name
|
|
33
|
-
<ul>
|
|
34
|
-
<li id='page1_12_24'/> page1_12 page1_12_24 [each]
|
|
35
|
-
<li id='page1_12_32'/> page1_12 page1_12_32 [each]
|
|
36
|
-
</ul>
|
|
37
|
-
</div>
|
|
38
|
-
=end
|
|
39
|
-
|
|
40
|
-
require 'yaml'
|
|
41
|
-
|
|
42
|
-
module Zena
|
|
43
|
-
module Parser
|
|
44
|
-
include RubyLess::SafeClass
|
|
45
|
-
# Zafu tags used to display / edit nodes and versions
|
|
46
|
-
module ZenaTags
|
|
47
|
-
PSEUDO_ATTRIBUTES = {
|
|
48
|
-
'now' => 'Time.now',
|
|
49
|
-
'start.id' => '(params[:s] || @node[:zip])',
|
|
50
|
-
'nil' => 'nil',
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
class << self
|
|
54
|
-
def inline_methods(*args)
|
|
55
|
-
args.each do |name|
|
|
56
|
-
class_eval <<-END
|
|
57
|
-
def r_#{name}
|
|
58
|
-
"<%= #{name}(:node=>\#{node}\#{params_to_erb(@params)}) %>"
|
|
59
|
-
end
|
|
60
|
-
END
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def direct_methods(*args)
|
|
65
|
-
args.each do |name|
|
|
66
|
-
class_eval <<-END
|
|
67
|
-
def r_#{name}
|
|
68
|
-
helper.#{name}
|
|
69
|
-
end
|
|
70
|
-
END
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
inline_methods :login_link, :visitor_link, :search_box, :show_menu, :show_path, :lang_links
|
|
75
|
-
direct_methods :uses_datebox
|
|
76
|
-
|
|
77
|
-
def before_render
|
|
78
|
-
return unless super
|
|
79
|
-
|
|
80
|
-
@var = nil # reset var counter
|
|
81
|
-
|
|
82
|
-
if key = @params[:store]
|
|
83
|
-
set_stored(Node, key, node)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
if key = @params[:store_date]
|
|
87
|
-
set_stored(Date, key, current_date)
|
|
88
|
-
end
|
|
89
|
-
@anchor_param = @params[:anchor]
|
|
90
|
-
|
|
91
|
-
true
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def do_method(sym)
|
|
95
|
-
method = sym
|
|
96
|
-
pre, post = '', ''
|
|
97
|
-
|
|
98
|
-
# do we need recursion ?
|
|
99
|
-
inc = descendant('include')
|
|
100
|
-
if inc && inc.params[:part] == @name
|
|
101
|
-
@context["#{@name}_method".to_sym] = method_name = template_url[1..-1].gsub(/[\/-]/,'_')
|
|
102
|
-
pre << "<% def #{method_name}(depth, node, list); return '' if depth > #{inc.params[:depth] ? [inc.params[:depth].to_i,30].min : 5}; _erbout = '' -%>"
|
|
103
|
-
post << "<% _erbout; end -%><%= #{method_name}(0,#{node},#{list || "[#{node}]"}) %>"
|
|
104
|
-
@context[:node] = 'node'
|
|
105
|
-
@context[:list] = 'list'
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
if @context[:make_form]
|
|
109
|
-
res = case method
|
|
110
|
-
when :r_title
|
|
111
|
-
make_input(:name => 'v_title')
|
|
112
|
-
when :r_link
|
|
113
|
-
make_input(:name => (@params[:attr] || 'v_title'))
|
|
114
|
-
when :r_show
|
|
115
|
-
make_input(:name => (@params[:attr] || @params[:tattr]), :date => @params[:date])
|
|
116
|
-
when :r_text
|
|
117
|
-
make_textarea(:name => 'v_text')
|
|
118
|
-
when :r_summary
|
|
119
|
-
make_textarea(:name => 'v_summary')
|
|
120
|
-
when :r_zazen
|
|
121
|
-
make_textarea(:name => @params[:attr])
|
|
122
|
-
else
|
|
123
|
-
if node_kind_of?(DataEntry) && @method.to_s =~ /node_/
|
|
124
|
-
# select node_id
|
|
125
|
-
"<%= select_id('#{base_class.to_s.underscore}', '#{@method}_id') %>"
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
res = "<#{@html_tag || 'div'} class='zazen'>#{res}</#{@html_tag || 'div'}>" if [:r_summary, :r_text].include?(sym)
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
res ||= super(method)
|
|
133
|
-
"#{pre}#{res}#{post}"
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
def after_render(text)
|
|
138
|
-
if @anchor_param
|
|
139
|
-
@params[:anchor] = @anchor_param # set back in case of double rendering so it is computed again
|
|
140
|
-
res = r_anchor + super
|
|
141
|
-
else
|
|
142
|
-
res = super
|
|
143
|
-
end
|
|
144
|
-
res
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
# Our special version of r_expand_with tag with "set_" parsing.
|
|
148
|
-
def r_expand_with
|
|
149
|
-
hash = {}
|
|
150
|
-
@params.each do |k,v|
|
|
151
|
-
if k.to_s =~ /^set_(.+)$/
|
|
152
|
-
# TODO: DRY with render_html_tag
|
|
153
|
-
k = $1
|
|
154
|
-
value, static = parse_attributes_in_value(v, :erb => false)
|
|
155
|
-
hash["exp_#{k}"] = static ? value.inspect : "\"#{value}\""
|
|
156
|
-
else
|
|
157
|
-
hash["exp_#{k}"] = v.inspect
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
@params = {}
|
|
161
|
-
expand_with(hash)
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
def r_show
|
|
165
|
-
if attr_or_date = @params[:attr_or_date]
|
|
166
|
-
# using [var] shortcut. Can be either a date or an attribute/var
|
|
167
|
-
if attr_or_date == 'current_date' || attr_or_date =~ /_at$/
|
|
168
|
-
@params[:date] = attr_or_date
|
|
169
|
-
else
|
|
170
|
-
@params[:attr] = attr_or_date
|
|
171
|
-
end
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
if var_name = @params[:var]
|
|
175
|
-
return parser_error("var #{@params[:var].inspect} not set") unless @context[:vars] && @context[:vars].include?(var_name)
|
|
176
|
-
attribute_method = "set_#{var_name}"
|
|
177
|
-
elsif @params[:eval]
|
|
178
|
-
return unless attribute_method = parse_eval_parameter(@params[:eval])
|
|
179
|
-
elsif @params[:tattr]
|
|
180
|
-
attribute_method = "_(#{node_attribute(@params[:tattr], :else=>@params[:else], :default=>@params[:default])})"
|
|
181
|
-
elsif @params[:attr]
|
|
182
|
-
attribute_method = node_attribute(@params[:attr], :else=>@params[:else], :default=>@params[:default])
|
|
183
|
-
elsif p = @params[:param]
|
|
184
|
-
return "<%= params[#{p.to_sym.inspect}] %>"
|
|
185
|
-
elsif @params[:date]
|
|
186
|
-
# date can be any attribute v_created_at or updated_at etc.
|
|
187
|
-
# TODO format with @params[:format] and @params[:tformat] << translated format
|
|
188
|
-
# TODO: test
|
|
189
|
-
if @params[:tformat]
|
|
190
|
-
format = _(@params[:tformat])
|
|
191
|
-
elsif @params[:format]
|
|
192
|
-
format = @params[:format]
|
|
193
|
-
else
|
|
194
|
-
format = "%Y-%m-%d"
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
tz = ''
|
|
198
|
-
lang = ''
|
|
199
|
-
if tz_name = @params[:time_zone]
|
|
200
|
-
tz_list = @params.reject {|k,v| !(k.to_s =~ /^time_zone\d*$/)}.to_a.sort {|a,b| a[0].to_s <=> b[0].to_s }.map do |k,tz_name|
|
|
201
|
-
if tz_name =~ /^\[(\w+)\]$/
|
|
202
|
-
node_attribute($1)
|
|
203
|
-
else
|
|
204
|
-
begin
|
|
205
|
-
TZInfo::Timezone.get(tz_name)
|
|
206
|
-
rescue TZInfo::InvalidTimezoneIdentifier
|
|
207
|
-
return parser_error("invalid timezone #{tz_name.inspect}")
|
|
208
|
-
end
|
|
209
|
-
tz_name.inspect
|
|
210
|
-
end
|
|
211
|
-
end
|
|
212
|
-
tz = ", #{tz_list.join(' || ')}"
|
|
213
|
-
end
|
|
214
|
-
if lang = @params[:lang]
|
|
215
|
-
tz = ', nil' if tz == ''
|
|
216
|
-
lang = ", #{lang.inspect}"
|
|
217
|
-
end
|
|
218
|
-
attribute_method = "format_date(#{node_attribute(@params[:date])}, #{format.inspect}#{tz}#{lang})"
|
|
219
|
-
elsif @context[:trans]
|
|
220
|
-
# error
|
|
221
|
-
return "no attribute for 'show'".inspect
|
|
222
|
-
else
|
|
223
|
-
return parser_error("missing attribute")
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
if !@params[:date] && fmt = @params[:format]
|
|
227
|
-
begin
|
|
228
|
-
# test argument
|
|
229
|
-
sprintf(fmt, 123.45)
|
|
230
|
-
rescue ArgumentError
|
|
231
|
-
return parser_error("incorect format #{fmt.inspect}")
|
|
232
|
-
end
|
|
233
|
-
if fmt =~ /%[\d\.]*f/
|
|
234
|
-
modifier = ".to_f"
|
|
235
|
-
elsif fmt =~ /%[\d\.]*i/
|
|
236
|
-
modifier = ".to_i"
|
|
237
|
-
else
|
|
238
|
-
modifier = ''
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
if @params[:zero] == 'hide'
|
|
242
|
-
attribute_method = "sprintf_unless_zero(#{fmt.inspect}, #{attribute_method}#{modifier})"
|
|
243
|
-
else
|
|
244
|
-
attribute_method = "sprintf(#{fmt.inspect}, #{attribute_method}#{modifier})"
|
|
245
|
-
end
|
|
246
|
-
end
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if @context[:trans]
|
|
250
|
-
# TODO: what do we do here with gsubs, url ?
|
|
251
|
-
return attribute_method
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
if gsub = @params[:gsub]
|
|
255
|
-
if gsub =~ /\A\/(.+)\/(.+)\/\Z/
|
|
256
|
-
value = $2
|
|
257
|
-
key = $1.gsub(/\#([\{\$\@])/,'# \1') # FIXME: SECURITY.
|
|
258
|
-
# Please note that .gsub(/#([\{\$\@])/,'\#\1') won't work, since '\#{blah}' will become '\\#{blah}' and 'blah' will be evaluated.
|
|
259
|
-
regexp_ok = begin
|
|
260
|
-
output = StringIO.open('','w')
|
|
261
|
-
$stderr = output
|
|
262
|
-
re = /#{key}/
|
|
263
|
-
output.string !~ /warning:/
|
|
264
|
-
rescue
|
|
265
|
-
false
|
|
266
|
-
ensure
|
|
267
|
-
$stderr = STDERR
|
|
268
|
-
false
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
if regexp_ok
|
|
272
|
-
attribute_method = "#{attribute_method}.to_s.gsub(/#{key}/,#{value.inspect})"
|
|
273
|
-
else
|
|
274
|
-
# invalid regexp
|
|
275
|
-
return parser_error("invalid gsub #{gsub.inspect}")
|
|
276
|
-
end
|
|
277
|
-
else
|
|
278
|
-
# error
|
|
279
|
-
return parser_error("invalid gsub #{gsub.inspect}")
|
|
280
|
-
end
|
|
281
|
-
end
|
|
282
|
-
|
|
283
|
-
if @params[:actions]
|
|
284
|
-
actions = "<%= node_actions(:node=>#{node}#{params_to_erb(:actions=>@params[:actions], :publish_after_save=>auto_publish_param)}) %>"
|
|
285
|
-
else
|
|
286
|
-
actions = ''
|
|
287
|
-
end
|
|
288
|
-
|
|
289
|
-
attribute = @params[:attr] || @params[:tattr] || @params[:date]
|
|
290
|
-
|
|
291
|
-
if (@params[:edit_preview] || @params[:ep]) == 'true'
|
|
292
|
-
@html_tag_params[:id] = "#{attribute}#{erb_node_id}"
|
|
293
|
-
@html_tag ||= 'span'
|
|
294
|
-
end
|
|
295
|
-
|
|
296
|
-
if @params[:edit] == 'true' && !['url','path'].include?(attribute)
|
|
297
|
-
"<% if #{node}.can_write? -%><span class='show_edit' id='#{erb_dom_id("_#{attribute}")}'>#{actions}<%= link_to_remote(#{attribute_method}, :url => edit_node_path(#{node_id}) + \"?attribute=#{attribute}&dom_id=#{dom_id("_#{attribute}")}#{auto_publish_param(true)}\", :method => :get) %></span><% else -%>#{actions}<%= #{attribute_method} %><% end -%>"
|
|
298
|
-
else
|
|
299
|
-
"#{actions}<%= #{attribute_method} %>"
|
|
300
|
-
end
|
|
301
|
-
end
|
|
302
|
-
|
|
303
|
-
def r_zazen
|
|
304
|
-
attribute = @params[:attr] || @params[:tattr]
|
|
305
|
-
limit = @params[:limit] ? ", :limit=>#{@params[:limit].to_i}" : ""
|
|
306
|
-
if @context[:trans]
|
|
307
|
-
# TODO: what do we do here with dates ?
|
|
308
|
-
return "#{node_attribute(attribute)}"
|
|
309
|
-
elsif @params[:tattr]
|
|
310
|
-
return "<%= zazen(_(#{node_attribute(attribute)})#{limit}, :node=>#{node(Node)}) %>"
|
|
311
|
-
elsif @params[:attr]
|
|
312
|
-
if output_format == 'html'
|
|
313
|
-
res = "<%= zazen(#{node_attribute(attribute)}#{limit}, :node=>#{node(Node)}) %>"
|
|
314
|
-
else
|
|
315
|
-
return "<%= zazen(#{node_attribute(attribute)}#{limit}, :node=>#{node(Node)}, :output=>#{output_format.inspect}) %>"
|
|
316
|
-
end
|
|
317
|
-
elsif @params[:date]
|
|
318
|
-
# date can be any attribute v_created_at or updated_at etc.
|
|
319
|
-
# TODO format with @params[:format] and @params[:tformat] << translated format
|
|
320
|
-
else
|
|
321
|
-
# error
|
|
322
|
-
end
|
|
323
|
-
|
|
324
|
-
@html_tag ||= 'div'
|
|
325
|
-
|
|
326
|
-
add_html_class('zazen')
|
|
327
|
-
|
|
328
|
-
if (@params[:edit_preview] || @params[:ep]) == 'true'
|
|
329
|
-
@html_tag_params[:id] = "#{attribute}#{erb_node_id}"
|
|
330
|
-
end
|
|
331
|
-
|
|
332
|
-
if @params[:edit] == 'true' && !['url','path'].include?(attribute)
|
|
333
|
-
edit_text = _('edit')
|
|
334
|
-
@html_tag_params[:id] = erb_dom_id("_#{attribute}")
|
|
335
|
-
res = "<% if #{node}.can_write? -%><span class='zazen_edit'><%= link_to_remote(#{edit_text.inspect}, :url => edit_node_path(#{node_id}) + \"?attribute=#{attribute}&dom_id=#{dom_id("_#{attribute}")}#{auto_publish_param(true)}&zazen=true\", :method => :get) %></span><% end -%>#{res}"
|
|
336
|
-
else
|
|
337
|
-
res
|
|
338
|
-
end
|
|
339
|
-
end
|
|
340
|
-
|
|
341
|
-
# TODO: test, rename ?
|
|
342
|
-
def r_search_results
|
|
343
|
-
do_list("@nodes")
|
|
344
|
-
end
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
def r_set
|
|
348
|
-
return parser_error("'var' missing") unless var_name = @params[:var]
|
|
349
|
-
return parser_error("bad value for 'var' (#{var_name.inspect})") unless var_name =~ /^[a-zA-Z_]+$/
|
|
350
|
-
return '' unless @context[:set]
|
|
351
|
-
if @params[:value]
|
|
352
|
-
out "<% set_#{var_name} = #{@params[:value].inspect} -%>"
|
|
353
|
-
# TODO: isn't @context[:vars] = @params[:value].inspect missing here ?
|
|
354
|
-
elsif @params[:eval]
|
|
355
|
-
return unless eval_string = parse_eval_parameter(@params[:eval])
|
|
356
|
-
out "<% set_#{var_name} = #{eval_string} -%>"
|
|
357
|
-
else
|
|
358
|
-
out "<% set_#{var_name} = capture do %>"
|
|
359
|
-
out expand_with(:set => false) # do not propagate
|
|
360
|
-
out "<% end -%>"
|
|
361
|
-
end
|
|
362
|
-
end
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
# TODO: write a test (please)
|
|
366
|
-
# FIXME: we should use a single way to change a whole context into a template (applies to 'each', 'form', 'block'). Then 'swap' could use the 'each' block.
|
|
367
|
-
# Define a block of elements to be used by ajax calls (edit/filter)
|
|
368
|
-
def r_block
|
|
369
|
-
if @context[:block] == self
|
|
370
|
-
# called from self (storing template)
|
|
371
|
-
@context.reject! do |k,v|
|
|
372
|
-
# FIXME: reject all stored elements in a better way then this
|
|
373
|
-
k.kind_of?(String) && k =~ /\ANode_\w/
|
|
374
|
-
end
|
|
375
|
-
@html_tag_done = false
|
|
376
|
-
@html_tag_params.merge!(:id=>erb_dom_id)
|
|
377
|
-
@context[:scope_node] = node if @context[:scope_node]
|
|
378
|
-
out expand_with(:node => node)
|
|
379
|
-
if @method == 'drop' && !@context[:make_form]
|
|
380
|
-
out drop_javascript
|
|
381
|
-
end
|
|
382
|
-
else
|
|
383
|
-
if parent.method == 'each' && @method == parent.single_child_method
|
|
384
|
-
# use parent as block
|
|
385
|
-
# FIXME: will not work with block as distant target...
|
|
386
|
-
# do nothing
|
|
387
|
-
else
|
|
388
|
-
@html_tag ||= 'div'
|
|
389
|
-
new_dom_scope
|
|
390
|
-
|
|
391
|
-
unless @context[:make_form]
|
|
392
|
-
# STORE TEMPLATE ========
|
|
393
|
-
|
|
394
|
-
context_bak = @context.dup # avoid side effects when rendering the same block
|
|
395
|
-
ignore_list = @method == 'block' ? ['form'] : [] # do not show the form in the normal template of a block
|
|
396
|
-
template = expand_block(self, :block=>self, :list=>false, :saved_template=>true, :ignore => ignore_list)
|
|
397
|
-
@context = context_bak
|
|
398
|
-
@result = ''
|
|
399
|
-
out helper.save_erb_to_url(template, template_url)
|
|
400
|
-
|
|
401
|
-
# STORE FORM ============
|
|
402
|
-
if edit = descendant('edit')
|
|
403
|
-
publish_after_save = (edit.params[:publish] == 'true')
|
|
404
|
-
if form = descendant('form')
|
|
405
|
-
# USE BLOCK FORM ========
|
|
406
|
-
form_text = expand_block(form, :saved_template=>true, :publish_after_save => publish_after_save)
|
|
407
|
-
else
|
|
408
|
-
# MAKE A FORM FROM BLOCK ========
|
|
409
|
-
form = self.dup
|
|
410
|
-
form.method = 'form'
|
|
411
|
-
form_text = expand_block(form, :make_form => true, :list => false, :saved_template => true, :publish_after_save => publish_after_save)
|
|
412
|
-
end
|
|
413
|
-
out helper.save_erb_to_url(form_text, form_url)
|
|
414
|
-
end
|
|
415
|
-
end
|
|
416
|
-
|
|
417
|
-
# RENDER
|
|
418
|
-
@html_tag_done = false
|
|
419
|
-
@html_tag_params.merge!(:id=>erb_dom_id)
|
|
420
|
-
end
|
|
421
|
-
|
|
422
|
-
out expand_with
|
|
423
|
-
if @method == 'drop' && !@context[:make_form]
|
|
424
|
-
out drop_javascript
|
|
425
|
-
end
|
|
426
|
-
end
|
|
427
|
-
end
|
|
428
|
-
|
|
429
|
-
# TODO: test
|
|
430
|
-
def r_filter
|
|
431
|
-
if upd = @params[:update]
|
|
432
|
-
return unless block = find_target(upd)
|
|
433
|
-
else
|
|
434
|
-
return parser_error("missing 'block' in same parent") unless parent && block = parent.descendant('block')
|
|
435
|
-
end
|
|
436
|
-
return parser_error("cannot use 's' as key (used by start_node)") if @params[:key] == 's'
|
|
437
|
-
out "<%= form_remote_tag(:url => zafu_node_path(#{node_id}), :method => :get, :html => {:id => \"#{dom_id}_f\"}) %><div class='hidden'><input type='hidden' name='t_url' value='#{block.template_url}'/><input type='hidden' name='dom_id' value='#{block.erb_dom_id}'/>#{start_node_s_param(:input)}</div><div class='wrapper'>"
|
|
438
|
-
if @blocks == []
|
|
439
|
-
out "<input type='text' name='#{@params[:key] || 'f'}' value='<%= params[#{(@params[:key] || 'f').to_sym.inspect}] %>'/>"
|
|
440
|
-
else
|
|
441
|
-
out expand_with(:in_filter => true)
|
|
442
|
-
end
|
|
443
|
-
out "</div></form>"
|
|
444
|
-
if @params[:live] || @params[:update]
|
|
445
|
-
out "<%= observe_form( \"#{dom_id}_f\" , :method => :get, :frequency => 1, :submit =>\"#{dom_id}_f\", :url => zafu_node_path(#{node_id})) %>"
|
|
446
|
-
end
|
|
447
|
-
end
|
|
448
|
-
|
|
449
|
-
# swap an attribute
|
|
450
|
-
# TODO: test
|
|
451
|
-
def r_swap
|
|
452
|
-
if upd = @params[:update]
|
|
453
|
-
if upd == '_page'
|
|
454
|
-
block = nil
|
|
455
|
-
elsif block = find_target(upd)
|
|
456
|
-
# ok
|
|
457
|
-
if ancestor('block') || ancestor('each')
|
|
458
|
-
upd_both = '&upd_both=true'
|
|
459
|
-
else
|
|
460
|
-
upd_both = ''
|
|
461
|
-
end
|
|
462
|
-
else
|
|
463
|
-
return
|
|
464
|
-
end
|
|
465
|
-
elsif ancestor('block') || ancestor('each')
|
|
466
|
-
# ancestor: ok
|
|
467
|
-
block = self
|
|
468
|
-
elsif parent && block = parent.descendant('block')
|
|
469
|
-
# sibling: ok
|
|
470
|
-
upd_both = ''
|
|
471
|
-
else
|
|
472
|
-
return parser_error("missing 'block' in same parent")
|
|
473
|
-
end
|
|
474
|
-
|
|
475
|
-
states = ((@params[:states] || 'todo, done') + ' ').split(',').map(&:strip)
|
|
476
|
-
|
|
477
|
-
query_params = "node[#{@params[:attr]}]=\#{#{states.inspect}[ ((#{states.inspect}.index(#{node_attribute(@params[:attr])}.to_s) || 0)+1) % #{states.size}]}#{upd_both}"
|
|
478
|
-
out link_to_update(block, :query_params => query_params, :method => :put, :html_params => get_html_params(@params, :link))
|
|
479
|
-
end
|
|
480
|
-
|
|
481
|
-
def r_load
|
|
482
|
-
if dict = @params[:dictionary]
|
|
483
|
-
dict_content, absolute_url, doc = self.class.get_template_text(dict, @options[:helper], @options[:current_folder])
|
|
484
|
-
return parser_error("dictionary #{dict.inspect} not found") unless doc
|
|
485
|
-
@context[:dict] ||= {}
|
|
486
|
-
begin
|
|
487
|
-
definitions = YAML::load(dict_content)
|
|
488
|
-
definitions['translations'].each do |elem|
|
|
489
|
-
@context[:dict][elem[0]] = elem[1]
|
|
490
|
-
end
|
|
491
|
-
rescue
|
|
492
|
-
return parser_error("invalid dictionary content #{dict.inspect}")
|
|
493
|
-
end
|
|
494
|
-
else
|
|
495
|
-
return parser_error("missing 'dictionary'")
|
|
496
|
-
end
|
|
497
|
-
expand_with
|
|
498
|
-
end
|
|
499
|
-
|
|
500
|
-
def r_trans
|
|
501
|
-
static = true
|
|
502
|
-
if @params[:text]
|
|
503
|
-
text = @params[:text]
|
|
504
|
-
elsif @params[:attr]
|
|
505
|
-
text = "#{node_attribute(@params[:attr])}"
|
|
506
|
-
static = false
|
|
507
|
-
else
|
|
508
|
-
res = []
|
|
509
|
-
text = ""
|
|
510
|
-
@blocks.each do |b|
|
|
511
|
-
if b.kind_of?(String)
|
|
512
|
-
res << b.inspect
|
|
513
|
-
text << b
|
|
514
|
-
elsif ['show', 'current_date'].include?(b.method)
|
|
515
|
-
res << expand_block(b, :trans=>true)
|
|
516
|
-
static = false
|
|
517
|
-
else
|
|
518
|
-
# ignore
|
|
519
|
-
end
|
|
520
|
-
end
|
|
521
|
-
unless static
|
|
522
|
-
text = res.join(' + ')
|
|
523
|
-
end
|
|
524
|
-
end
|
|
525
|
-
if static
|
|
526
|
-
_(text)
|
|
527
|
-
else
|
|
528
|
-
"<%= _(#{text}) %>"
|
|
529
|
-
end
|
|
530
|
-
end
|
|
531
|
-
|
|
532
|
-
alias r_t r_trans
|
|
533
|
-
|
|
534
|
-
def r_anchor(obj=node)
|
|
535
|
-
"<a name='#{anchor_name(@anchor_param, obj)}'></a>"
|
|
536
|
-
end
|
|
537
|
-
|
|
538
|
-
def anchor_name(p, obj=node)
|
|
539
|
-
if p =~ /\[(.+)\]/
|
|
540
|
-
"<%= #{node_attribute($1)} %>"
|
|
541
|
-
else
|
|
542
|
-
"#{base_class.to_s.underscore}#{erb_node_id(obj)}"
|
|
543
|
-
end
|
|
544
|
-
end
|
|
545
|
-
|
|
546
|
-
def r_content_for_layout
|
|
547
|
-
"<% if content_for_layout = yield -%><%= content_for_layout %><% else -%>" +
|
|
548
|
-
expand_with +
|
|
549
|
-
"<% end -%>"
|
|
550
|
-
end
|
|
551
|
-
|
|
552
|
-
def r_title_for_layout
|
|
553
|
-
"<% if @title_for_layout -%><%= @title_for_layout %><% elsif @node && !@node.new_record? -%><%= @node.rootpath %><% elsif @node.parent -%><%= @node.parent.rootpath %><% else -%>" +
|
|
554
|
-
expand_with +
|
|
555
|
-
"<% end -%>"
|
|
556
|
-
end
|
|
557
|
-
|
|
558
|
-
def r_check_lang
|
|
559
|
-
text = @params[:text] || expand_with
|
|
560
|
-
klass = @params[:class] || @html_tag_params[:class]
|
|
561
|
-
text = nil if text.blank?
|
|
562
|
-
klas = nil if klass.blank?
|
|
563
|
-
@html_tag_done = true
|
|
564
|
-
"#{@space_before}<%= check_lang(#{node},:text=>#{text.inspect},:class=>#{klass.inspect},:wrap=>#{@html_tag.inspect}) %>"
|
|
565
|
-
end
|
|
566
|
-
|
|
567
|
-
def r_title
|
|
568
|
-
if node_kind_of?(Version)
|
|
569
|
-
node = "#{self.node}.node"
|
|
570
|
-
elsif node_kind_of?(Node)
|
|
571
|
-
node = self.node
|
|
572
|
-
else
|
|
573
|
-
return parser_error('title','only works with nodes')
|
|
574
|
-
end
|
|
575
|
-
title_params = {}
|
|
576
|
-
|
|
577
|
-
title_params[:check_lang] = @params[:check_lang] if @params.include?(:check_lang)
|
|
578
|
-
|
|
579
|
-
if @params[:link]
|
|
580
|
-
value, static = parse_attributes_in_value(@params[:link], :erb => false)
|
|
581
|
-
link_param = ", :link=>\"#{value}\""
|
|
582
|
-
else
|
|
583
|
-
link_param = ''
|
|
584
|
-
end
|
|
585
|
-
|
|
586
|
-
res = "<%= show_title(:node=>#{node}#{link_param}#{params_to_erb(title_params)}"
|
|
587
|
-
if @params[:text]
|
|
588
|
-
res << ", :text=>#{@params[:text].inspect}"
|
|
589
|
-
elsif @params[:attr]
|
|
590
|
-
res << ", :text=>#{node_attribute(@params[:attr])}"
|
|
591
|
-
end
|
|
592
|
-
|
|
593
|
-
if @params.include?(:project)
|
|
594
|
-
res << ", :project=>#{@params[:project] == 'true'}"
|
|
595
|
-
end
|
|
596
|
-
res << ")"
|
|
597
|
-
if @params[:actions]
|
|
598
|
-
res << " + node_actions(:node=>#{node}#{params_to_erb(:actions=>@params[:actions], :publish_after_save=>auto_publish_param)})"
|
|
599
|
-
end
|
|
600
|
-
res << "%>"
|
|
601
|
-
if @params[:status] == 'true' || (@params[:status].nil? && @params[:actions])
|
|
602
|
-
@html_tag ||= 'span'
|
|
603
|
-
add_html_class("s<%= #{node}.version.status %>")
|
|
604
|
-
end
|
|
605
|
-
res
|
|
606
|
-
end
|
|
607
|
-
|
|
608
|
-
# TODO: test
|
|
609
|
-
def r_actions
|
|
610
|
-
out expand_with
|
|
611
|
-
out "<%= node_actions(:node=>#{node}#{params_to_erb(:actions=>@params[:select], :publish_after_save=>auto_publish_param)}) %>"
|
|
612
|
-
end
|
|
613
|
-
|
|
614
|
-
# TODO: test
|
|
615
|
-
def r_admin_links
|
|
616
|
-
"<%= show_link(:admin_links).join('</#{@html_tag}><#{@html_tag}>') %>"
|
|
617
|
-
end
|
|
618
|
-
|
|
619
|
-
def r_text
|
|
620
|
-
text = @params[:text] ? @params[:text].inspect : "#{node_attribute('v_text')}"
|
|
621
|
-
limit = @params[:limit] ? ", :limit=>#{@params[:limit].to_i}" : ""
|
|
622
|
-
|
|
623
|
-
@html_tag ||= 'div'
|
|
624
|
-
|
|
625
|
-
if @html_tag_params[:id]
|
|
626
|
-
# add a sub-div
|
|
627
|
-
pre = "<div id='v_text#{erb_node_id}'>"
|
|
628
|
-
post = "</div>"
|
|
629
|
-
else
|
|
630
|
-
pre = post = ''
|
|
631
|
-
@html_tag_params[:id] = "v_text#{erb_node_id}"
|
|
632
|
-
end
|
|
633
|
-
|
|
634
|
-
add_html_class('zazen')
|
|
635
|
-
|
|
636
|
-
unless @params[:empty] == 'true'
|
|
637
|
-
out "#{pre}<% if #{node}.kind_of?(TextDocument); l = #{node}.content_lang -%>"
|
|
638
|
-
out "<%= zazen(\"<code\#{l ? \" lang='\#{l}'\" : ''} class=\\'full\\'>\#{#{text}}</code>\") %>"
|
|
639
|
-
out "<% else -%>"
|
|
640
|
-
out "<%= zazen(#{text}#{limit}, :node=>#{node(Node)}) %>"
|
|
641
|
-
out "<% end -%>#{post}"
|
|
642
|
-
else
|
|
643
|
-
out "#{pre}#{post}"
|
|
644
|
-
end
|
|
645
|
-
end
|
|
646
|
-
|
|
647
|
-
def r_inspect
|
|
648
|
-
out ["params: #{@params.inspect}",
|
|
649
|
-
"name: #{@context[:name]}",
|
|
650
|
-
"node: #{node}",
|
|
651
|
-
"list: #{list}"].join("<br/>")
|
|
652
|
-
end
|
|
653
|
-
|
|
654
|
-
# TODO: replace with a more general 'zazen' or 'show' with id ?
|
|
655
|
-
def r_summary
|
|
656
|
-
limit = @params[:limit] ? ", :limit=>#{@params[:limit].to_i}" : ""
|
|
657
|
-
@html_tag ||= 'div'
|
|
658
|
-
if @html_tag_params[:id]
|
|
659
|
-
# add a sub-div
|
|
660
|
-
pre = "<div id='v_summary#{erb_node_id}'>"
|
|
661
|
-
post = "</div>"
|
|
662
|
-
else
|
|
663
|
-
pre = post = ''
|
|
664
|
-
@html_tag_params[:id] = "v_summary#{erb_node_id}"
|
|
665
|
-
end
|
|
666
|
-
|
|
667
|
-
add_html_class('zazen')
|
|
668
|
-
|
|
669
|
-
unless @params[:or]
|
|
670
|
-
text = @params[:text] ? @params[:text].inspect : node_attribute('v_summary')
|
|
671
|
-
out "#{pre}<%= zazen(#{text}#{limit}, :node=>#{node(Node)}) %>#{post}"
|
|
672
|
-
else
|
|
673
|
-
limit ||= ', :limit => 2'
|
|
674
|
-
first_name = 'v_summary'
|
|
675
|
-
first = node_attribute(first_name)
|
|
676
|
-
|
|
677
|
-
second_name = @params[:or].gsub(/[^a-z_]/,'') # FIXME: ist this still needed ? (ERB injection)
|
|
678
|
-
second = node_attribute(second_name)
|
|
679
|
-
out "#{pre}<% if #{first} != '' %>"
|
|
680
|
-
out "<%= zazen(#{first}, :node=>#{node(Node)}) %>"
|
|
681
|
-
out "<% else %>"
|
|
682
|
-
out "<%= zazen(#{second}#{limit}, :node=>#{node(Node)}) %>"
|
|
683
|
-
out "<% end %>#{post}"
|
|
684
|
-
end
|
|
685
|
-
end
|
|
686
|
-
|
|
687
|
-
def r_show_author
|
|
688
|
-
if @params[:size] == 'large'
|
|
689
|
-
out "#{_("posted by")} <b><%= #{node}.author.fullname %></b>"
|
|
690
|
-
out "<% if #{node}[:user_id] != #{node}.version[:user_id] -%>"
|
|
691
|
-
out "<% if #{node}[:ref_lang] != #{node}.version[:lang] -%>"
|
|
692
|
-
out "#{_("traduction by")} <b><%= #{node}.version.author.fullname %></b>"
|
|
693
|
-
out "<% else -%>"
|
|
694
|
-
out "#{_("modified by")} <b><%= #{node}.version.author.fullname %></b>"
|
|
695
|
-
out "<% end"
|
|
696
|
-
out " end -%>"
|
|
697
|
-
out " #{_("on")} <%= format_date(#{node}.version.updated_at, #{_('short_date').inspect}) %>."
|
|
698
|
-
if @params[:traductions] == 'true'
|
|
699
|
-
out " #{_("Traductions")} : <span class='traductions'><%= helper.traductions(:node=>#{node}).join(', ') %></span>"
|
|
700
|
-
end
|
|
701
|
-
else
|
|
702
|
-
out "<b><%= #{node}.version.author.initials %></b> - <%= format_date(#{node}.version.updated_at, #{_('short_date').inspect}) %>"
|
|
703
|
-
if @params[:traductions] == 'true'
|
|
704
|
-
out " <span class='traductions'>(<%= helper.traductions(:node=>#{node}).join(', ') %>)</span>"
|
|
705
|
-
end
|
|
706
|
-
end
|
|
707
|
-
end
|
|
708
|
-
|
|
709
|
-
def r_comments_to_publish
|
|
710
|
-
open_context("visitor.comments_to_publish", :node_class => [Comment])
|
|
711
|
-
end
|
|
712
|
-
|
|
713
|
-
def r_to_publish
|
|
714
|
-
open_context("visitor.to_publish", :node_class => [Version])
|
|
715
|
-
end
|
|
716
|
-
|
|
717
|
-
def r_proposed
|
|
718
|
-
open_context("visitor.proposed", :node_class => [Version])
|
|
719
|
-
end
|
|
720
|
-
|
|
721
|
-
def r_redactions
|
|
722
|
-
open_context("visitor.redactions", :node_class => [Version])
|
|
723
|
-
end
|
|
724
|
-
|
|
725
|
-
def r_edit
|
|
726
|
-
|
|
727
|
-
if @context[:dom_prefix]
|
|
728
|
-
# ajax
|
|
729
|
-
if @context[:in_form]
|
|
730
|
-
# cancel button
|
|
731
|
-
@context[:form_cancel] || ''
|
|
732
|
-
else
|
|
733
|
-
# edit button
|
|
734
|
-
|
|
735
|
-
# TODO: show 'reply' instead of 'edit' in comments if visitor != author
|
|
736
|
-
out link_to_update(self, :default_text => _('edit'), :url => "\#{edit_#{base_class.to_s.underscore}_path(#{node_id})}", :html_params => get_html_params(@params, :link), :method => :get, :cond => "#{node}.can_write?", :else => :void)
|
|
737
|
-
end
|
|
738
|
-
else
|
|
739
|
-
# FIXME: we could link to some html page to edit the item.
|
|
740
|
-
""
|
|
741
|
-
end
|
|
742
|
-
end
|
|
743
|
-
|
|
744
|
-
alias r_cancel r_edit
|
|
745
|
-
|
|
746
|
-
def r_textarea
|
|
747
|
-
out make_textarea(@html_tag_params.merge(@params))
|
|
748
|
-
@html_tag_done = true
|
|
749
|
-
end
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
# <r:select name='klass' root_class='...'/>
|
|
753
|
-
# <r:select name='parent_id' values='projects in site'/>
|
|
754
|
-
# TODO: optimization (avoid loading full AR to only use [id, name])
|
|
755
|
-
def r_select
|
|
756
|
-
html_attributes, attribute = get_input_params()
|
|
757
|
-
return parser_error("missing name") unless attribute
|
|
758
|
-
if value = @params[:selected]
|
|
759
|
-
# FIXME: DRY with html_attributes
|
|
760
|
-
value = value.gsub(/\[([^\]]+)\]/) do
|
|
761
|
-
node_attr = $1
|
|
762
|
-
res = node_attribute(node_attr)
|
|
763
|
-
"\#{#{res}}"
|
|
764
|
-
end
|
|
765
|
-
selected = value.inspect
|
|
766
|
-
elsif @context[:in_filter]
|
|
767
|
-
selected = "params[#{attribute.to_sym.inspect}].to_s"
|
|
768
|
-
else
|
|
769
|
-
selected = "#{node_attribute(attribute)}.to_s"
|
|
770
|
-
end
|
|
771
|
-
html_id = html_attributes[:id] ? " id='#{html_attributes[:id]}'" : ''
|
|
772
|
-
if @context[:in_filter]
|
|
773
|
-
select_tag = "<select#{html_id} name='#{attribute}'>"
|
|
774
|
-
else
|
|
775
|
-
select_tag = "<select#{html_id} name='#{base_class.to_s.underscore}[#{attribute}]'>"
|
|
776
|
-
end
|
|
777
|
-
|
|
778
|
-
if klass = @params[:root_class]
|
|
779
|
-
class_opts = {}
|
|
780
|
-
class_opts[:without] = @params[:without] if @params[:without]
|
|
781
|
-
# do not use 'selected' if the node is not new
|
|
782
|
-
"#{select_tag}<%= options_for_select(Node.classes_for_form(:class => #{klass.inspect}#{params_to_erb(class_opts)}), (#{node}.new_record? ? #{selected} : #{node}.klass)) %></select>"
|
|
783
|
-
elsif @params[:type] == 'time_zone'
|
|
784
|
-
# <r:select name='d_tz' type='time_zone'/>
|
|
785
|
-
"#{select_tag}<%= options_for_select(TZInfo::Timezone.all_identifiers, #{selected}) %></select>"
|
|
786
|
-
elsif options_list = get_options_for_select
|
|
787
|
-
"#{select_tag}<%= options_for_select(#{options_list}, #{selected}) %></select>"
|
|
788
|
-
else
|
|
789
|
-
parser_error("missing 'nodes', 'root_class' or 'values'")
|
|
790
|
-
end
|
|
791
|
-
end
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
def r_input
|
|
795
|
-
html_attributes, attribute = get_input_params()
|
|
796
|
-
case @params[:type]
|
|
797
|
-
when 'select' # FIXME: why is this only for classes ?
|
|
798
|
-
out parser_error("please use [select] here")
|
|
799
|
-
r_select
|
|
800
|
-
when 'date_box', 'date'
|
|
801
|
-
return parser_error("date_box without name") unless attribute
|
|
802
|
-
input_id = @context[:dom_prefix] ? ", :id=>\"#{dom_id}_#{attribute}\"" : ''
|
|
803
|
-
"<%= date_box '#{base_class.to_s.underscore}', #{attribute.inspect}, :size=>15#{@context[:in_add] ? ", :value=>''" : ''}#{input_id} %>"
|
|
804
|
-
when 'id'
|
|
805
|
-
return parser_error("select id without name") unless attribute
|
|
806
|
-
name = "#{attribute}_id" unless attribute[-3..-1] == '_id'
|
|
807
|
-
input_id = @context[:erb_dom_id] ? ", :input_id =>\"#{erb_dom_id}_#{attribute}\"" : ''
|
|
808
|
-
"<%= select_id('#{base_class.to_s.underscore}', #{attribute.inspect}#{input_id}) %>"
|
|
809
|
-
when 'time_zone'
|
|
810
|
-
out parser_error("please use [select] here")
|
|
811
|
-
r_select
|
|
812
|
-
when 'submit'
|
|
813
|
-
@html_tag = 'input'
|
|
814
|
-
@html_tag_params[:type] = @params[:type]
|
|
815
|
-
@html_tag_params[:text] = @params[:text] if @params[:text]
|
|
816
|
-
@html_tag_params.merge!(html_attributes)
|
|
817
|
-
render_html_tag(nil)
|
|
818
|
-
else
|
|
819
|
-
# 'text', 'hidden', ...
|
|
820
|
-
@html_tag = 'input'
|
|
821
|
-
@html_tag_params[:type] = @params[:type] || 'text'
|
|
822
|
-
if checked = html_attributes.delete(:checked)
|
|
823
|
-
@html_tag_params.merge!(html_attributes)
|
|
824
|
-
render_html_tag(nil, checked)
|
|
825
|
-
else
|
|
826
|
-
@html_tag_params.merge!(html_attributes)
|
|
827
|
-
render_html_tag(nil)
|
|
828
|
-
end
|
|
829
|
-
end
|
|
830
|
-
end
|
|
831
|
-
|
|
832
|
-
def r_form_tag
|
|
833
|
-
# replace <form> with constructed form
|
|
834
|
-
"#{@context[:form_tag]}#{expand_with(:form_tag => nil)}</form>"
|
|
835
|
-
end
|
|
836
|
-
|
|
837
|
-
# TODO: add parent_id into the form !
|
|
838
|
-
# TODO: add <div style="margin:0;padding:0"><input name="_method" type="hidden" value="put" /></div> if method == put
|
|
839
|
-
# FIXME: use <r:form href='self'> or <r:form action='...'>
|
|
840
|
-
def r_form
|
|
841
|
-
hidden_fields = {}
|
|
842
|
-
set_fields = []
|
|
843
|
-
id_hash = {:class => @html_tag_params[:class] || @params[:class] || 'form'}
|
|
844
|
-
var_name = base_class.to_s.underscore
|
|
845
|
-
(descendants('input') + descendants('select')).each do |tag|
|
|
846
|
-
set_fields << "#{var_name}[#{tag.params[:name]}]"
|
|
847
|
-
end
|
|
848
|
-
|
|
849
|
-
if @context[:dom_prefix] || @params[:update]
|
|
850
|
-
# ajax
|
|
851
|
-
if @context[:in_add]
|
|
852
|
-
# inline form used to create new elements: set values to '' and 'parent_id' from context
|
|
853
|
-
id_hash[:id] = "#{erb_dom_id}_form"
|
|
854
|
-
id_hash[:style] = "display:none;"
|
|
855
|
-
|
|
856
|
-
cancel = "<p class='btn_x'><a href='#' onclick='[\"#{erb_dom_id}_add\", \"#{erb_dom_id}_form\"].each(Element.toggle);return false;'>#{_('btn_x')}</a></p>\n"
|
|
857
|
-
form = "<%= form_remote_tag(:url => #{base_class.to_s.underscore.pluralize}_path, :html => {:id => \"#{dom_id}_form_t\"}) %>\n"
|
|
858
|
-
else
|
|
859
|
-
# saved form
|
|
860
|
-
|
|
861
|
-
id_hash[:id] = erb_dom_id
|
|
862
|
-
|
|
863
|
-
cancel = !@context[:dom_prefix] ? "" : <<-END_TXT
|
|
864
|
-
<% if #{node}.new_record? -%>
|
|
865
|
-
<p class='btn_x'><a href='#' onclick='[\"<%= params[:dom_id] %>_add\", \"<%= params[:dom_id] %>_form\"].each(Element.toggle);return false;'>#{_('btn_x')}</a></p>
|
|
866
|
-
<% else -%>
|
|
867
|
-
<p class='btn_x'><%= link_to_remote(#{_('btn_x').inspect}, :url => #{base_class.to_s.underscore}_path(#{node_id}) + \"/zafu?t_url=#{CGI.escape(template_url)}&dom_id=\#{params[:dom_id]}#{@context[:need_link_id] ? "&link_id=\#{#{node}.link_id}" : ''}\", :method => :get) %></p>
|
|
868
|
-
<% end -%>
|
|
869
|
-
END_TXT
|
|
870
|
-
form =<<-END_TXT
|
|
871
|
-
<% if #{node}.new_record? -%>
|
|
872
|
-
<%= form_remote_tag(:url => #{base_class.to_s.underscore.pluralize}_path, :html => {:id => \"\#{params[:dom_id]}_form_t\"}) %>
|
|
873
|
-
<% else -%>
|
|
874
|
-
<%= form_remote_tag(:url => #{base_class.to_s.underscore}_path(#{node_id}), :method => :put, :html => {:id => \"#{dom_id}_form_t\"}) %>
|
|
875
|
-
<% end -%>
|
|
876
|
-
END_TXT
|
|
877
|
-
end
|
|
878
|
-
|
|
879
|
-
if (descendants('input') || []).select{|elem| elem.params[:type] == 'submit'} != []
|
|
880
|
-
# has submit
|
|
881
|
-
else
|
|
882
|
-
hidden_submit = "<input type='submit'/>" # hidden submit for Firefox compatibility
|
|
883
|
-
end
|
|
884
|
-
|
|
885
|
-
hidden_fields['link_id'] = "<%= #{node}.link_id %>" if @context[:need_link_id]
|
|
886
|
-
|
|
887
|
-
if @params[:update] || (@context[:add] && @context[:add].params[:update])
|
|
888
|
-
upd = @params[:update] || @context[:add].params[:update]
|
|
889
|
-
if target = find_target(upd)
|
|
890
|
-
hidden_fields['u_url'] = target.template_url
|
|
891
|
-
hidden_fields['udom_id'] = target.erb_dom_id
|
|
892
|
-
hidden_fields['u_id'] = "<%= #{@context[:parent_node]}.zip %>" if @context[:in_add]
|
|
893
|
-
hidden_fields['s'] = start_node_s_param(:value)
|
|
894
|
-
end
|
|
895
|
-
elsif (block = ancestor('block')) && node_kind_of?(DataEntry)
|
|
896
|
-
# updates template url
|
|
897
|
-
hidden_fields['u_url'] = block.template_url
|
|
898
|
-
hidden_fields['udom_id'] = block.erb_dom_id
|
|
899
|
-
end
|
|
900
|
-
|
|
901
|
-
hidden_fields['t_url'] = template_url
|
|
902
|
-
if t_id = @params[:t_id]
|
|
903
|
-
hidden_fields['t_id'] = parse_attributes_in_value(t_id)
|
|
904
|
-
end
|
|
905
|
-
|
|
906
|
-
erb_dom_id = @context[:saved_template] ? '<%= params[:dom_id] %>' : self.erb_dom_id
|
|
907
|
-
|
|
908
|
-
hidden_fields['dom_id'] = erb_dom_id
|
|
909
|
-
|
|
910
|
-
if node_kind_of?(Node)
|
|
911
|
-
hidden_fields['node[parent_id]'] = "<%= #{@context[:in_add] ? "#{@context[:parent_node]}.zip" : "#{node}.parent_zip"} %>"
|
|
912
|
-
elsif node_kind_of?(Comment)
|
|
913
|
-
# FIXME: the "... || '@node'" is a hack and I don't understand why it's needed...
|
|
914
|
-
hidden_fields['node_id'] = "<%= #{@context[:parent_node] || '@node'}.zip %>"
|
|
915
|
-
elsif node_kind_of?(DataEntry)
|
|
916
|
-
hidden_fields["data_entry[#{@context[:data_root]}_id]"] = "<%= #{@context[:in_add] ? @context[:parent_node] : "#{node}.#{@context[:data_root]}"}.zip %>"
|
|
917
|
-
end
|
|
918
|
-
|
|
919
|
-
if add_block = @context[:add]
|
|
920
|
-
params = add_block.params
|
|
921
|
-
[:after, :before, :top, :bottom].each do |sym|
|
|
922
|
-
if params[sym]
|
|
923
|
-
hidden_fields['position'] = sym.to_s
|
|
924
|
-
if params[sym] == 'self'
|
|
925
|
-
if sym == :before
|
|
926
|
-
hidden_fields['reference'] = "#{erb_dom_id}_add"
|
|
927
|
-
else
|
|
928
|
-
hidden_fields['reference'] = "#{erb_dom_id}_form"
|
|
929
|
-
end
|
|
930
|
-
else
|
|
931
|
-
hidden_fields['reference'] = params[sym]
|
|
932
|
-
end
|
|
933
|
-
break
|
|
934
|
-
end
|
|
935
|
-
end
|
|
936
|
-
if params[:done] == 'focus'
|
|
937
|
-
if params[:focus]
|
|
938
|
-
hidden_fields['done'] = "'$(\"#{erb_dom_id}_#{@params[:focus]}\").focus();'"
|
|
939
|
-
else
|
|
940
|
-
hidden_fields['done'] = "'$(\"#{erb_dom_id}_form_t\").focusFirstElement();'"
|
|
941
|
-
end
|
|
942
|
-
elsif params[:done]
|
|
943
|
-
hidden_fields['done'] = CGI.escape(params[:done]) # .gsub("NODE_ID", @node.zip).gsub("PARENT_ID", @node.parent_zip)
|
|
944
|
-
end
|
|
945
|
-
else
|
|
946
|
-
# ajax form, not in 'add'
|
|
947
|
-
hidden_fields['done'] = CGI.escape(@params[:done]) if @params[:done]
|
|
948
|
-
end
|
|
949
|
-
else
|
|
950
|
-
# no ajax
|
|
951
|
-
# FIXME
|
|
952
|
-
cancel = "" # link to normal node ?
|
|
953
|
-
form = "<form method='post' action='/nodes/#{erb_node_id}'><div style='margin:0;padding:0'><input name='_method' type='hidden' value='put' /></div>"
|
|
954
|
-
end
|
|
955
|
-
|
|
956
|
-
if node_kind_of?(Node) && (@params[:klass] || @context[:klass])
|
|
957
|
-
hidden_fields['node[klass]'] = @params[:klass] || @context[:klass]
|
|
958
|
-
end
|
|
959
|
-
|
|
960
|
-
if node_kind_of?(Node) && @params[:mode]
|
|
961
|
-
hidden_fields['mode'] = @params[:mode]
|
|
962
|
-
end
|
|
963
|
-
|
|
964
|
-
hidden_fields['node[v_status]'] = Zena::Status[:pub] if @context[:publish_after_save] || auto_publish_param
|
|
965
|
-
|
|
966
|
-
form << "<div class='hidden'>"
|
|
967
|
-
hidden_fields.each do |k,v|
|
|
968
|
-
next if set_fields.include?(k)
|
|
969
|
-
v = "'#{v}'" unless v.kind_of?(String) && ['"', "'"].include?(v[0..0])
|
|
970
|
-
form << "<input type='hidden' name='#{k}' value=#{v}/>\n"
|
|
971
|
-
end
|
|
972
|
-
form << hidden_submit << "\n" if hidden_submit
|
|
973
|
-
form << "</div>"
|
|
974
|
-
|
|
975
|
-
form << "<%= error_messages_for(#{node}) %>"
|
|
976
|
-
|
|
977
|
-
if !descendant('cancel') && !descendant('edit')
|
|
978
|
-
if !descendant('form_tag')
|
|
979
|
-
# add a descendant before blocks.
|
|
980
|
-
blocks_bak = @blocks
|
|
981
|
-
@blocks = @blocks.dup
|
|
982
|
-
@blocks = [make(:void, :method=>'void', :text=>cancel)] + blocks_bak
|
|
983
|
-
else
|
|
984
|
-
form = cancel + form
|
|
985
|
-
cancel = ''
|
|
986
|
-
end
|
|
987
|
-
end
|
|
988
|
-
|
|
989
|
-
if descendant('form_tag')
|
|
990
|
-
res = expand_with(:form_tag => form, :in_form => true, :form_cancel => cancel, :erb_dom_id => erb_dom_id, :dom_id => dom_id)
|
|
991
|
-
else
|
|
992
|
-
res = form + expand_with(:in_form => true, :form_cancel => cancel, :erb_dom_id => erb_dom_id, :dom_id => dom_id) + '</form>'
|
|
993
|
-
end
|
|
994
|
-
|
|
995
|
-
@blocks = blocks_bak if blocks_bak
|
|
996
|
-
|
|
997
|
-
@html_tag_done = false
|
|
998
|
-
@html_tag_params.merge!(id_hash)
|
|
999
|
-
out render_html_tag(res)
|
|
1000
|
-
end
|
|
1001
|
-
|
|
1002
|
-
# <r:checkbox role='collaborator_for' values='projects' in='site'/>"
|
|
1003
|
-
# TODO: implement checkbox in the same spirit as 'r_select'
|
|
1004
|
-
def r_checkbox
|
|
1005
|
-
return parser_error("missing 'nodes'") unless values = @params[:values] || @params[:nodes]
|
|
1006
|
-
return parser_error("missing 'role'") unless role = (@params[:role] || @params[:name])
|
|
1007
|
-
attribute = @params[:attr] || 'name'
|
|
1008
|
-
if role =~ /(.*)_ids?\Z/
|
|
1009
|
-
role = $1
|
|
1010
|
-
end
|
|
1011
|
-
meth = role.singularize
|
|
1012
|
-
|
|
1013
|
-
if values =~ /^\d+\s*($|,)/
|
|
1014
|
-
# ids
|
|
1015
|
-
# TODO generate the full query instead of using secure.
|
|
1016
|
-
values = values.split(',').map{|v| v.to_i}
|
|
1017
|
-
list_finder = "(secure(Node) { Node.find(:all, :conditions => 'zip IN (#{values.join(',')})') })"
|
|
1018
|
-
else
|
|
1019
|
-
# relation
|
|
1020
|
-
list_finder, klass = build_finder_for(:all, values)
|
|
1021
|
-
return unless list_finder
|
|
1022
|
-
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
|
1023
|
-
end
|
|
1024
|
-
out "<% if (#{list_var} = #{list_finder}) && (#{list_var}_relation = #{node}.relation_proxy(#{role.inspect})) -%>"
|
|
1025
|
-
out "<% if #{list_var}_relation.unique? -%>"
|
|
1026
|
-
|
|
1027
|
-
out "<% #{list_var}_id = #{list_var}_relation.other_id -%>"
|
|
1028
|
-
out "<div class='input_radio'><% #{list_var}.each do |#{var}| -%>"
|
|
1029
|
-
out "<span><input type='radio' name='node[#{meth}_id]' value='#{erb_node_id(var)}'<%= #{list_var}_id == #{var}[:id] ? \" checked='checked'\" : '' %>/> <%= #{node_attribute(attribute, :node=>var)} %></span> "
|
|
1030
|
-
out "<% end -%></div>"
|
|
1031
|
-
out "<input type='radio' name='node[#{meth}_id]' value=''/> #{_('none')}"
|
|
1032
|
-
|
|
1033
|
-
out "<% else -%>"
|
|
1034
|
-
|
|
1035
|
-
out "<% #{list_var}_ids = #{list_var}_relation.other_ids -%>"
|
|
1036
|
-
out "<div class='input_checkbox'><% #{list_var}.each do |#{var}| -%>"
|
|
1037
|
-
out "<span><input type='checkbox' name='node[#{meth}_ids][]' value='#{erb_node_id(var)}'<%= #{list_var}_ids.include?(#{var}[:id]) ? \" checked='checked'\" : '' %>/> <%= #{node_attribute(attribute, :node=>var)} %></span> "
|
|
1038
|
-
out "<% end -%></div>"
|
|
1039
|
-
out "<input type='hidden' name='node[#{meth}_ids][]' value=''/>"
|
|
1040
|
-
|
|
1041
|
-
out "<% end -%><% end -%>"
|
|
1042
|
-
end
|
|
1043
|
-
|
|
1044
|
-
alias r_radio r_checkbox
|
|
1045
|
-
|
|
1046
|
-
# TODO: test
|
|
1047
|
-
def r_add
|
|
1048
|
-
return parser_error("should not be called from within 'each'") if parent.method == 'each'
|
|
1049
|
-
return '' if @context[:make_form]
|
|
1050
|
-
|
|
1051
|
-
# why is node = @node (which we need) but we are supposed to have Comments ?
|
|
1052
|
-
# FIXME: during rewrite, replace 'node' by 'node(klass = node_class)' so the ugly lines below would be
|
|
1053
|
-
# if node_kind_of?(Comment)
|
|
1054
|
-
# out "<% if #{node(Node)}.can_comment? -%>"
|
|
1055
|
-
# Refs #198.
|
|
1056
|
-
if node_kind_of?(Comment)
|
|
1057
|
-
out "<% if #{node}.can_comment? -%>"
|
|
1058
|
-
else
|
|
1059
|
-
out "<% if #{node}.can_write? -%>"
|
|
1060
|
-
end
|
|
1061
|
-
|
|
1062
|
-
unless descendant('add_btn')
|
|
1063
|
-
# add a descendant between self and blocks.
|
|
1064
|
-
blocks = @blocks.dup
|
|
1065
|
-
@blocks = []
|
|
1066
|
-
add_btn = make(:void, :method=>'add_btn', :params=>@params.dup, :text=>'')
|
|
1067
|
-
add_btn.blocks = blocks
|
|
1068
|
-
remove_instance_variable(:@all_descendants)
|
|
1069
|
-
end
|
|
1070
|
-
|
|
1071
|
-
if @context[:form] && @context[:dom_prefix]
|
|
1072
|
-
# ajax add
|
|
1073
|
-
|
|
1074
|
-
@html_tag_params.merge!(:id => "#{erb_dom_id}_add")
|
|
1075
|
-
@html_tag_params[:class] ||= 'btn_add'
|
|
1076
|
-
if @params[:focus]
|
|
1077
|
-
focus = "$(\"#{erb_dom_id}_#{@params[:focus]}\").focus();"
|
|
1078
|
-
else
|
|
1079
|
-
focus = "$(\"#{erb_dom_id}_form_t\").focusFirstElement();"
|
|
1080
|
-
end
|
|
1081
|
-
|
|
1082
|
-
out render_html_tag("#{expand_with(:onclick=>"[\"#{erb_dom_id}_add\", \"#{erb_dom_id}_form\"].each(Element.toggle);#{focus}return false;")}")
|
|
1083
|
-
|
|
1084
|
-
if node_kind_of?(Node)
|
|
1085
|
-
# FIXME: BUG if we set <r:form klass='Post'/> the user cannot select class with menu...
|
|
1086
|
-
klass = @context[:klass] || 'Node'
|
|
1087
|
-
# FIXME: inspect '@context[:form]' to see if it contains v_klass ?
|
|
1088
|
-
out "<% if #{var}_new = secure(Node) { Node.new_from_class(#{klass.inspect}) } -%>"
|
|
1089
|
-
else
|
|
1090
|
-
out "<% if #{var}_new = #{node_class}.new -%>"
|
|
1091
|
-
end
|
|
1092
|
-
|
|
1093
|
-
if @context[:form].method == 'form'
|
|
1094
|
-
out expand_block(@context[:form], :in_add => true, :no_ignore => ['form'], :add=>self, :node => "#{var}_new", :parent_node => node, :klass => klass, :publish_after_save => auto_publish_param)
|
|
1095
|
-
else
|
|
1096
|
-
# build form from 'each'
|
|
1097
|
-
out expand_block(@context[:form], :in_add => true, :no_ignore => ['form'], :add=>self, :make_form => true, :node => "#{var}_new", :parent_node => node, :klass => klass, :publish_after_save => auto_publish_param)
|
|
1098
|
-
end
|
|
1099
|
-
out "<% end -%>"
|
|
1100
|
-
else
|
|
1101
|
-
# no ajax
|
|
1102
|
-
@html_tag_params[:class] ||= 'btn_add' if @html_tag
|
|
1103
|
-
out render_html_tag(expand_with)
|
|
1104
|
-
end
|
|
1105
|
-
out "<% end -%>"
|
|
1106
|
-
@html_tag_done = true
|
|
1107
|
-
end
|
|
1108
|
-
|
|
1109
|
-
def r_add_btn
|
|
1110
|
-
if @params[:text]
|
|
1111
|
-
text = @params[:text]
|
|
1112
|
-
text = "<div>#{text}</div>" unless @html_tag
|
|
1113
|
-
elsif @params[:trans]
|
|
1114
|
-
text = _(@params[:trans])
|
|
1115
|
-
text = "<div>#{text}</div>" unless @html_tag
|
|
1116
|
-
elsif @blocks != []
|
|
1117
|
-
text = expand_with
|
|
1118
|
-
else
|
|
1119
|
-
text = node_class == Comment ? _("btn_add_comment") : _("btn_add")
|
|
1120
|
-
end
|
|
1121
|
-
|
|
1122
|
-
out "<a href='#' onclick='#{@context[:onclick]}'>#{text}</a>"
|
|
1123
|
-
end
|
|
1124
|
-
|
|
1125
|
-
# Show html to add open a popup window to add a document.
|
|
1126
|
-
# TODO: inline ajax for upload ?
|
|
1127
|
-
def r_add_document
|
|
1128
|
-
return parser_error("only works with nodes (not with #{node_class})") unless node_kind_of?(Node)
|
|
1129
|
-
@html_tag_params[:class] ||= 'btn_add'
|
|
1130
|
-
res = "<a href='/documents/new?parent_id=#{erb_node_id}' onclick='uploader=window.open(\"/documents/new?parent_id=#{erb_node_id}\", \"upload\", \"width=400,height=300\");return false;'>#{_('btn_add_doc')}</a>"
|
|
1131
|
-
"<% if #{node}.can_write? -%>#{render_html_tag(res)}<% end -%>"
|
|
1132
|
-
end
|
|
1133
|
-
|
|
1134
|
-
#if RAILS_ENV == 'test'
|
|
1135
|
-
# def r_test
|
|
1136
|
-
# inspect
|
|
1137
|
-
# end
|
|
1138
|
-
#end
|
|
1139
|
-
|
|
1140
|
-
def r_drop
|
|
1141
|
-
if parent.method == 'each' && @method == parent.single_child_method
|
|
1142
|
-
parent.add_html_class('drop')
|
|
1143
|
-
else
|
|
1144
|
-
@html_tag_params[:class] ||= 'drop'
|
|
1145
|
-
end
|
|
1146
|
-
r_block
|
|
1147
|
-
end
|
|
1148
|
-
|
|
1149
|
-
def drop_javascript
|
|
1150
|
-
hover = @params[:hover]
|
|
1151
|
-
change = @params[:change]
|
|
1152
|
-
|
|
1153
|
-
if role = @params[:set] || @params[:add]
|
|
1154
|
-
query_params = ["node[#{role}_id]=[id]"]
|
|
1155
|
-
else
|
|
1156
|
-
query_params = []
|
|
1157
|
-
# set='icon_for=[id], v_status='50', v_title='[v_title]'
|
|
1158
|
-
@params.each do |k, v|
|
|
1159
|
-
next if [:hover, :change, :done].include?(k)
|
|
1160
|
-
value, static = parse_attributes_in_value(v, :erb => false, :skip_node_attributes => true)
|
|
1161
|
-
key = change == 'params' ? "params[#{k}]" : "node[#{k}]"
|
|
1162
|
-
query_params << "#{key}=#{CGI.escape(value)}"
|
|
1163
|
-
end
|
|
1164
|
-
return parser_error("missing parameters to set values") if query_params == []
|
|
1165
|
-
end
|
|
1166
|
-
|
|
1167
|
-
query_params << "change=#{change}" if change == 'receiver'
|
|
1168
|
-
query_params << "t_url=#{CGI.escape(template_url)}"
|
|
1169
|
-
query_params << "dom_id=#{erb_dom_id}"
|
|
1170
|
-
query_params << start_node_s_param(:erb)
|
|
1171
|
-
query_params << "done=#{CGI.escape(@params[:done])}" if @params[:done]
|
|
1172
|
-
|
|
1173
|
-
"<script type='text/javascript'>
|
|
1174
|
-
//<![CDATA[
|
|
1175
|
-
Droppables.add('#{erb_dom_id}', {hoverclass:'#{hover || 'drop_hover'}', onDrop:function(element){new Ajax.Request('/nodes/#{erb_node_id}/drop?#{query_params.join('&')}', {asynchronous:true, evalScripts:true, method:'put', parameters:'drop=' + encodeURIComponent(element.id)})}})
|
|
1176
|
-
//]]>
|
|
1177
|
-
</script>"
|
|
1178
|
-
end
|
|
1179
|
-
|
|
1180
|
-
def r_draggable
|
|
1181
|
-
new_dom_scope
|
|
1182
|
-
@html_tag ||= 'div'
|
|
1183
|
-
case @params[:revert]
|
|
1184
|
-
when 'move'
|
|
1185
|
-
revert_effect = 'Element.move'
|
|
1186
|
-
when 'remove'
|
|
1187
|
-
revert_effect = 'Element.remove'
|
|
1188
|
-
else
|
|
1189
|
-
revert_effect = 'Element.move'
|
|
1190
|
-
end
|
|
1191
|
-
|
|
1192
|
-
res, drag_handle = set_drag_handle_and_id(expand_with, @params, :id => erb_dom_id)
|
|
1193
|
-
|
|
1194
|
-
out render_html_tag(res)
|
|
1195
|
-
|
|
1196
|
-
if drag_handle
|
|
1197
|
-
out "<script type='text/javascript'>\n//<![CDATA[\n
|
|
1198
|
-
new Draggable('#{erb_dom_id}', {ghosting:true, revert:true, revertEffect:#{revert_effect}, handle:$('#{erb_dom_id}').select('.#{drag_handle}')[0]});\n//]]>\n</script>"
|
|
1199
|
-
else
|
|
1200
|
-
out "<script type='text/javascript'>\n//<![CDATA[\nZena.draggable('#{erb_dom_id}',0,true,true,#{revert_effect})\n//]]>\n</script>"
|
|
1201
|
-
end
|
|
1202
|
-
end
|
|
1203
|
-
|
|
1204
|
-
def r_unlink
|
|
1205
|
-
return "" if @context[:make_form]
|
|
1206
|
-
opts = {}
|
|
1207
|
-
|
|
1208
|
-
if upd = @params[:update]
|
|
1209
|
-
if upd == '_page'
|
|
1210
|
-
target = nil
|
|
1211
|
-
elsif target = find_target(upd)
|
|
1212
|
-
# ok
|
|
1213
|
-
else
|
|
1214
|
-
return
|
|
1215
|
-
end
|
|
1216
|
-
elsif target = ancestor('block')
|
|
1217
|
-
# ok
|
|
1218
|
-
else
|
|
1219
|
-
target = self
|
|
1220
|
-
end
|
|
1221
|
-
|
|
1222
|
-
if node_kind_of?(Node)
|
|
1223
|
-
opts[:cond] = "#{node}.can_write? && #{node}.link_id"
|
|
1224
|
-
opts[:url] = "/nodes/\#{#{node_id}}/links/\#{#{node}.link_id}"
|
|
1225
|
-
elsif node_kind_of?(Link)
|
|
1226
|
-
opts[:url] = "/nodes/\#{#{node}.this_zip}/links/\#{#{node}.zip}"
|
|
1227
|
-
end
|
|
1228
|
-
|
|
1229
|
-
opts[:method] = :delete
|
|
1230
|
-
opts[:default_text] = _('btn_tiny_del')
|
|
1231
|
-
opts[:html_params] = get_html_params({:class => 'unlink'}.merge(@params), :link)
|
|
1232
|
-
|
|
1233
|
-
out link_to_update(target, opts)
|
|
1234
|
-
|
|
1235
|
-
#tag_to_remote
|
|
1236
|
-
#"<%= tag_to_remote({:url => node_path(#{node_id}) + \"#{opts[:method] != :put ? '/zafu' : ''}?#{action.join('&')}\", :method => #{opts[:method].inspect}}) %>"
|
|
1237
|
-
# out "<a class='#{@params[:class] || 'unlink'}' href='/nodes/#{erb_node_id}/links/<%= #{node}.link_id %>?#{action}' onclick=\"new Ajax.Request('/nodes/#{erb_node_id}/links/<%= #{node}.link_id %>?#{action}', {asynchronous:true, evalScripts:true, method:'delete'}); return false;\">"
|
|
1238
|
-
# if !@blocks.empty?
|
|
1239
|
-
# inner = expand_with
|
|
1240
|
-
# else
|
|
1241
|
-
# inner = _('btn_tiny_del')
|
|
1242
|
-
# end
|
|
1243
|
-
# out "#{inner}</a><% else -%>#{inner}<% end -%>"
|
|
1244
|
-
#elsif node_kind_of?(DataEntry)
|
|
1245
|
-
# text = get_text_for_erb
|
|
1246
|
-
# if text.blank?
|
|
1247
|
-
# text = _('btn_tiny_del')
|
|
1248
|
-
# end
|
|
1249
|
-
# out "<%= link_to_remote(#{text.inspect}, {:url => \"/data_entries/\#{#{node}[:id]}?dom_id=#{dom_id}#{upd_url}\", :method => :delete}, :class=>#{(@params[:class] || 'unlink').inspect}) %>"
|
|
1250
|
-
#end
|
|
1251
|
-
end
|
|
1252
|
-
|
|
1253
|
-
# Group elements in a list. Use :order to specify order.
|
|
1254
|
-
def r_group
|
|
1255
|
-
return parser_error("cannot be used outside of a list") unless list_var = @context[:list]
|
|
1256
|
-
return parser_error("missing 'by' clause") unless key = @params[:by]
|
|
1257
|
-
|
|
1258
|
-
sort_key = @params[:sort] || 'name'
|
|
1259
|
-
if node_kind_of?(DataEntry) && DataEntry::NodeLinkSymbols.include?(key.to_sym)
|
|
1260
|
-
key = "#{key}_id"
|
|
1261
|
-
sort_block = "{|e| (e.#{key} || {})[#{sort_key.to_sym.inspect}]}"
|
|
1262
|
-
group_array = "group_array(#{list_var}) {|e| e.#{key}}"
|
|
1263
|
-
elsif node_kind_of?(Node)
|
|
1264
|
-
if ['project', 'parent', 'section'].include?(key)
|
|
1265
|
-
sort_block = "{|e| (e.#{key} || {})[#{sort_key.to_sym.inspect}]}"
|
|
1266
|
-
group_array = "group_array(#{list_var}) {|e| e.#{key}_id}"
|
|
1267
|
-
end
|
|
1268
|
-
end
|
|
1269
|
-
|
|
1270
|
-
group_array ||= "group_array(#{list_var}) {|e| #{node_attribute(key, :node => 'e')}}"
|
|
1271
|
-
|
|
1272
|
-
if sort_block
|
|
1273
|
-
out "<% grp_#{list_var} = sort_array(#{group_array}) #{sort_block} -%>"
|
|
1274
|
-
else
|
|
1275
|
-
out "<% grp_#{list_var} = #{group_array} -%>"
|
|
1276
|
-
end
|
|
1277
|
-
|
|
1278
|
-
if descendant('each_group')
|
|
1279
|
-
out expand_with(:group => "grp_#{list_var}")
|
|
1280
|
-
else
|
|
1281
|
-
@context[:group] = "grp_#{list_var}"
|
|
1282
|
-
r_each_group
|
|
1283
|
-
end
|
|
1284
|
-
end
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
# Compute statistics on elements in the current list context.
|
|
1288
|
-
def r_stat
|
|
1289
|
-
return parser_error("must be used inside a list context") unless list
|
|
1290
|
-
find = @params[:find] || @params[:date] || 'count'
|
|
1291
|
-
key = @params[:of] || @params[:from] || 'value'
|
|
1292
|
-
case find
|
|
1293
|
-
when 'sum'
|
|
1294
|
-
value = "#{list}.flatten.inject(0) {|#{var}_sum,#{var}| #{var}_sum + #{node_attribute(key, :node => var)}.to_f}"
|
|
1295
|
-
when 'min'
|
|
1296
|
-
value = "#{node_attribute(key, :node => "min_array(#{list}) {|e| #{node_attribute(key, :node => 'e')}}")}"
|
|
1297
|
-
when 'max'
|
|
1298
|
-
value = "#{node_attribute(key, :node => "max_array(#{list}) {|e| #{node_attribute(key, :node => 'e')}}")}"
|
|
1299
|
-
when 'count'
|
|
1300
|
-
return "<%= #{list}.size %>"
|
|
1301
|
-
end
|
|
1302
|
-
if @params[:date]
|
|
1303
|
-
# FIXME: DRY (r_show)
|
|
1304
|
-
if @params[:tformat]
|
|
1305
|
-
format = _(@params[:tformat])
|
|
1306
|
-
elsif @params[:format]
|
|
1307
|
-
format = @params[:format]
|
|
1308
|
-
else
|
|
1309
|
-
format = "%Y-%m-%d"
|
|
1310
|
-
end
|
|
1311
|
-
"<%= #{list}==[] ? '' : format_date(#{value}, #{format.inspect}) %>"
|
|
1312
|
-
elsif format = @params[:format]
|
|
1313
|
-
|
|
1314
|
-
if @params[:zero] == 'hide'
|
|
1315
|
-
"<%= #{list}==[] ? '' : sprintf_unless_zero(#{@params[:format].inspect}, #{value}) %>"
|
|
1316
|
-
else
|
|
1317
|
-
"<%= #{list}==[] ? '' : sprintf(#{@params[:format].inspect}, #{value}) %>"
|
|
1318
|
-
end
|
|
1319
|
-
else
|
|
1320
|
-
"<%= #{list}==[] ? '' : #{value} %>"
|
|
1321
|
-
end
|
|
1322
|
-
end
|
|
1323
|
-
|
|
1324
|
-
def r_each_group
|
|
1325
|
-
return parser_error("must be used inside a group context") unless group = @context[:group]
|
|
1326
|
-
if join = @params[:join]
|
|
1327
|
-
join = join.gsub(/<([^%])/, '<\1').gsub(/([^%])>/, '\1>')
|
|
1328
|
-
out "<% #{group}.each_index do |#{list_var}_index| -%>"
|
|
1329
|
-
out "<%= #{list_var}=#{group}[#{list_var}_index]; #{var} = #{list_var}[0]; #{list_var}_index > 0 ? #{join.inspect} : '' %>"
|
|
1330
|
-
else
|
|
1331
|
-
out "<% #{group}.each do |#{list_var}|; #{var} = #{list_var}[0]; -%>"
|
|
1332
|
-
end
|
|
1333
|
-
out render_html_tag(expand_with(:group => nil, :list => list_var, :node => var, :scope_node => var))
|
|
1334
|
-
out "<% end -%>"
|
|
1335
|
-
end
|
|
1336
|
-
|
|
1337
|
-
def r_each
|
|
1338
|
-
is_draggable = @params[:draggable] == 'true' || @params[:drag_handle]
|
|
1339
|
-
|
|
1340
|
-
if descendant('edit') || descendant('unlink') || descendant('swap') || ['block', 'drop'].include?(single_child_method) || is_draggable
|
|
1341
|
-
id_hash = {:id => erb_dom_id}
|
|
1342
|
-
else
|
|
1343
|
-
id_hash = nil
|
|
1344
|
-
end
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
if @context[:make_form]
|
|
1348
|
-
# use the elements inside 'each' loop to produce the edit form
|
|
1349
|
-
r_form
|
|
1350
|
-
elsif @context[:list]
|
|
1351
|
-
# normal rendering: not the start of a saved template
|
|
1352
|
-
if is_draggable || descendant('unlink')
|
|
1353
|
-
out "<% #{var}_dom_ids = [] -%>"
|
|
1354
|
-
end
|
|
1355
|
-
|
|
1356
|
-
@params[:alt_class] ||= @html_tag_params.delete(:alt_class)
|
|
1357
|
-
# FIXME: add alt_reverse='true' to start counting from bottom (if order last on top...)
|
|
1358
|
-
if @params[:alt_class] || @params[:join]
|
|
1359
|
-
join = @params[:join] || ''
|
|
1360
|
-
join = join.gsub(/<([^%])/, '<\1').gsub(/([^%])>/, '\1>')
|
|
1361
|
-
out "<% #{var}_max_index = #{list}.size - 1 -%>" if @params[:alt_reverse]
|
|
1362
|
-
out "<% #{list}.each_with_index do |#{var},#{var}_index| -%>"
|
|
1363
|
-
|
|
1364
|
-
if join_clause = @params[:join_if]
|
|
1365
|
-
set_stored(Node, 'prev', "#{var}_prev")
|
|
1366
|
-
cond = get_test_condition(var, :test=>join_clause)
|
|
1367
|
-
out "<%= #{var}_prev = #{list}[#{var}_index - 1]; (#{var}_index > 0 && #{cond}) ? #{join.inspect} : '' %>"
|
|
1368
|
-
else
|
|
1369
|
-
out "<%= #{var}_index > 0 ? #{join.inspect} : '' %>"
|
|
1370
|
-
end
|
|
1371
|
-
|
|
1372
|
-
if alt_class = @params[:alt_class]
|
|
1373
|
-
alt_test = @params[:alt_reverse] == 'true' ? "(#{var}_max_index - #{var}_index) % 2 != 0" : "#{var}_index % 2 != 0"
|
|
1374
|
-
if html_class = @html_tag_params.delete(:class)
|
|
1375
|
-
html_append = " class='#{html_class}<%= #{alt_test} ? #{(' ' + alt_class).inspect} : '' %>'"
|
|
1376
|
-
else
|
|
1377
|
-
html_append = "<%= #{alt_test} ? ' class=#{alt_class.inspect}' : '' %>"
|
|
1378
|
-
end
|
|
1379
|
-
else
|
|
1380
|
-
html_append = nil
|
|
1381
|
-
end
|
|
1382
|
-
else
|
|
1383
|
-
out "<% #{list}.each do |#{var}| -%>"
|
|
1384
|
-
html_append = nil
|
|
1385
|
-
end
|
|
1386
|
-
|
|
1387
|
-
if is_draggable
|
|
1388
|
-
out "<% #{var}_dom_ids << \"#{dom_id}\" -%>"
|
|
1389
|
-
end
|
|
1390
|
-
|
|
1391
|
-
out r_anchor(var) if @anchor_param # insert anchor inside the each loop
|
|
1392
|
-
@params[:anchor] = @anchor_param # set back in case we double render
|
|
1393
|
-
@anchor_param = nil
|
|
1394
|
-
|
|
1395
|
-
res, drag_handle = set_drag_handle_and_id(expand_with(:node => var, :scope_node => var), @params, id_hash)
|
|
1396
|
-
|
|
1397
|
-
out render_html_tag(res, html_append)
|
|
1398
|
-
|
|
1399
|
-
out "<% end -%>"
|
|
1400
|
-
|
|
1401
|
-
if is_draggable
|
|
1402
|
-
if drag_handle
|
|
1403
|
-
out "<script type='text/javascript'>\n//<![CDATA[\n<%= #{var}_dom_ids.inspect %>.each(function(dom_id, index) {
|
|
1404
|
-
new Draggable(dom_id, {ghosting:true, revert:true, handle:$(dom_id).select('.#{drag_handle}')[0]});
|
|
1405
|
-
});\n//]]>\n</script>"
|
|
1406
|
-
else
|
|
1407
|
-
out "<script type='text/javascript'>\n//<![CDATA[\n<%= #{var}_dom_ids.inspect %>.each(Zena.draggable)\n//]]>\n</script>"
|
|
1408
|
-
end
|
|
1409
|
-
end
|
|
1410
|
-
|
|
1411
|
-
elsif @context[:saved_template]
|
|
1412
|
-
# render to start a saved template
|
|
1413
|
-
res, drag_handle = set_drag_handle_and_id(expand_with(:scope_node => node), @params, id_hash)
|
|
1414
|
-
|
|
1415
|
-
out render_html_tag(res)
|
|
1416
|
-
|
|
1417
|
-
if is_draggable
|
|
1418
|
-
if drag_handle
|
|
1419
|
-
out "<script type='text/javascript'>\n//<![CDATA[\nnew Draggable('#{erb_dom_id}', {ghosting:true, revert:true, handle:$('#{erb_dom_id}').select('.#{drag_handle}')[0]});\n//]]>\n</script>"
|
|
1420
|
-
else
|
|
1421
|
-
out "<script type='text/javascript'>\n//<![CDATA[\nZena.draggable('#{erb_dom_id}')\n//]]>\n</script>"
|
|
1422
|
-
end
|
|
1423
|
-
end
|
|
1424
|
-
else
|
|
1425
|
-
# TODO: make a single list ?
|
|
1426
|
-
@context[:list] = "[#{node}]"
|
|
1427
|
-
r_each
|
|
1428
|
-
end
|
|
1429
|
-
end
|
|
1430
|
-
|
|
1431
|
-
def r_case
|
|
1432
|
-
out "<% if false -%>"
|
|
1433
|
-
out expand_with(:in_if=>true, :only=>['when', 'else'], :html_tag => @html_tag, :html_tag_params => @html_tag_params)
|
|
1434
|
-
@html_tag_done = true
|
|
1435
|
-
out "<% end -%>"
|
|
1436
|
-
end
|
|
1437
|
-
|
|
1438
|
-
# TODO: test
|
|
1439
|
-
def r_if
|
|
1440
|
-
cond = get_test_condition
|
|
1441
|
-
return parser_error("condition error") unless cond
|
|
1442
|
-
|
|
1443
|
-
if cond == 'true'
|
|
1444
|
-
return expand_with(:in_if => false)
|
|
1445
|
-
elsif cond == 'false'
|
|
1446
|
-
if descendant('else') || descendant('elsif')
|
|
1447
|
-
return expand_with(:in_if=>true, :only=>['elsif', 'else'])
|
|
1448
|
-
else
|
|
1449
|
-
@html_tag_done = true
|
|
1450
|
-
return ''
|
|
1451
|
-
end
|
|
1452
|
-
end
|
|
1453
|
-
|
|
1454
|
-
out "<% if #{cond} -%>"
|
|
1455
|
-
out render_html_tag(expand_with(:in_if=>false))
|
|
1456
|
-
out expand_with(:in_if=>true, :only=>['elsif', 'else'], :html_tag => @html_tag, :html_tag_params => @html_tag_params)
|
|
1457
|
-
out "<% end -%>"
|
|
1458
|
-
end
|
|
1459
|
-
|
|
1460
|
-
def r_else
|
|
1461
|
-
if @context[:in_if]
|
|
1462
|
-
@html_tag = @context[:html_tag]
|
|
1463
|
-
@html_tag_params = @context[:html_tag_params] || {}
|
|
1464
|
-
out "<% elsif true -%>"
|
|
1465
|
-
if @params[:text]
|
|
1466
|
-
out render_html_tag(@params[:text])
|
|
1467
|
-
else
|
|
1468
|
-
out render_html_tag(expand_with(:in_if=>false, :only => nil)) # do not propagate :only from ancestor 'if' clause
|
|
1469
|
-
end
|
|
1470
|
-
else
|
|
1471
|
-
""
|
|
1472
|
-
end
|
|
1473
|
-
end
|
|
1474
|
-
|
|
1475
|
-
def r_elsif
|
|
1476
|
-
return '' unless @context[:in_if]
|
|
1477
|
-
@html_tag = @context[:html_tag]
|
|
1478
|
-
@html_tag_params = @context[:html_tag_params] || {}
|
|
1479
|
-
cond = get_test_condition
|
|
1480
|
-
return parser_error("condition error") unless cond
|
|
1481
|
-
out "<% elsif #{cond} -%>"
|
|
1482
|
-
out render_html_tag(expand_with(:in_if=>false, :only => nil)) # do not propagate :only from ancestor 'if' clause
|
|
1483
|
-
end
|
|
1484
|
-
|
|
1485
|
-
def r_when
|
|
1486
|
-
r_elsif
|
|
1487
|
-
end
|
|
1488
|
-
|
|
1489
|
-
# be carefull, this gives a list of 'versions', not 'nodes'
|
|
1490
|
-
def r_traductions
|
|
1491
|
-
if @params[:except]
|
|
1492
|
-
case @params[:except]
|
|
1493
|
-
when 'current'
|
|
1494
|
-
opts = "(:conditions=>\"lang != '#{helper.lang}'\")"
|
|
1495
|
-
else
|
|
1496
|
-
# list of lang
|
|
1497
|
-
# TODO: test
|
|
1498
|
-
langs = @params[:except].split(',').map{|l| l.gsub(/[^a-z]/,'').strip }
|
|
1499
|
-
opts = "(:conditions=>\"lang NOT IN ('#{langs.join("','")}')\")"
|
|
1500
|
-
end
|
|
1501
|
-
elsif @params[:only]
|
|
1502
|
-
# TODO: test
|
|
1503
|
-
case @params[:only]
|
|
1504
|
-
when 'current'
|
|
1505
|
-
opts = "(:conditions=>\"lang = '#{helper.lang}'\")"
|
|
1506
|
-
else
|
|
1507
|
-
# list of lang
|
|
1508
|
-
# TODO: test
|
|
1509
|
-
langs = @params[:only].split(',').map{|l| l.gsub(/[^a-z]/,'').strip }
|
|
1510
|
-
opts = "(:conditions=>\"lang IN ('#{langs.join("','")}')\")"
|
|
1511
|
-
end
|
|
1512
|
-
else
|
|
1513
|
-
opts = ""
|
|
1514
|
-
end
|
|
1515
|
-
out "<% if #{list_var} = #{node}.traductions#{opts} -%>"
|
|
1516
|
-
out expand_with(:list=>list_var, :node_class => Version)
|
|
1517
|
-
out "<% end -%>"
|
|
1518
|
-
end
|
|
1519
|
-
|
|
1520
|
-
# TODO: test
|
|
1521
|
-
def r_show_traductions
|
|
1522
|
-
"<% if #{list_var} = #{node}.traductions -%>"
|
|
1523
|
-
"#{_("Traductions:")} <span class='traductions'><%= #{list_var}.join(', ') %></span>"
|
|
1524
|
-
"<%= traductions(:node=>#{node}).join(', ') %>"
|
|
1525
|
-
end
|
|
1526
|
-
|
|
1527
|
-
def r_node
|
|
1528
|
-
@method = @params[:select] || 'node' # 'node' is for version.node
|
|
1529
|
-
r_unknown
|
|
1530
|
-
end
|
|
1531
|
-
|
|
1532
|
-
# icon or first image (defined using build_finder_for instead of zafu_known_context for performance reasons).
|
|
1533
|
-
def r_icon
|
|
1534
|
-
if !@params[:in] && !@params[:where] && !@params[:from] && !@params[:find]
|
|
1535
|
-
finder, klass = build_finder_for(:first, 'icon', @params.merge(:or => 'image', :order => 'l_id desc, position asc, name asc', :group => 'id,l_id'))
|
|
1536
|
-
return unless finder
|
|
1537
|
-
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
|
1538
|
-
do_var(finder, :node_class => klass)
|
|
1539
|
-
else
|
|
1540
|
-
r_unknown
|
|
1541
|
-
end
|
|
1542
|
-
end
|
|
1543
|
-
|
|
1544
|
-
def r_date
|
|
1545
|
-
select = @params[:select]
|
|
1546
|
-
case select
|
|
1547
|
-
when 'main'
|
|
1548
|
-
expand_with(:date=>'main_date')
|
|
1549
|
-
when 'now'
|
|
1550
|
-
expand_with(:date=>'Time.now')
|
|
1551
|
-
else
|
|
1552
|
-
if select =~ /^\d{4}-\d{1,2}-\d{1,2}$/
|
|
1553
|
-
begin
|
|
1554
|
-
d = Date.parse(select)
|
|
1555
|
-
expand_with(:date=>select.inspect)
|
|
1556
|
-
rescue
|
|
1557
|
-
parser_error("invalid date '#{select}' should be 'YYYY-MM-DD'")
|
|
1558
|
-
end
|
|
1559
|
-
elsif date = find_stored(Date, select)
|
|
1560
|
-
if date[0..0] == '"'
|
|
1561
|
-
begin
|
|
1562
|
-
d = Date.parse(date[1..-2])
|
|
1563
|
-
expand_with(:date=>date)
|
|
1564
|
-
rescue
|
|
1565
|
-
parser_error("invalid date #{select} (#{date}) should be 'YYYY-MM-DD'")
|
|
1566
|
-
end
|
|
1567
|
-
else
|
|
1568
|
-
expand_with(:date=>select)
|
|
1569
|
-
end
|
|
1570
|
-
elsif select =~ /\[(.*)\]/
|
|
1571
|
-
date, static = parse_attributes_in_value(select, :erb => false)
|
|
1572
|
-
expand_with(:date => "\"#{date}\"")
|
|
1573
|
-
else
|
|
1574
|
-
parser_error("bad parameter '#{select}'")
|
|
1575
|
-
end
|
|
1576
|
-
end
|
|
1577
|
-
end
|
|
1578
|
-
|
|
1579
|
-
def r_javascripts
|
|
1580
|
-
if @params[:list].nil?
|
|
1581
|
-
list = %w{ prototype effects tablekit zena }
|
|
1582
|
-
elsif @params[:list] == 'all'
|
|
1583
|
-
list = %w{ prototype effects dragdrop tablekit zena }
|
|
1584
|
-
else
|
|
1585
|
-
list = @params[:list].split(',').map{|e| e.strip}
|
|
1586
|
-
end
|
|
1587
|
-
helper.javascript_include_tag(*list)
|
|
1588
|
-
end
|
|
1589
|
-
|
|
1590
|
-
def r_stylesheets
|
|
1591
|
-
if @params[:list] == 'all' || @params[:list].nil?
|
|
1592
|
-
list = %w{ zena code }
|
|
1593
|
-
else
|
|
1594
|
-
list = @params[:list].split(',').map{|e| e.strip}
|
|
1595
|
-
end
|
|
1596
|
-
list << {:media => @params[:media]} if @params[:media]
|
|
1597
|
-
helper.stylesheet_link_tag(*list)
|
|
1598
|
-
end
|
|
1599
|
-
|
|
1600
|
-
def r_flash_messages
|
|
1601
|
-
type = @params[:show] || 'both'
|
|
1602
|
-
"<div id='messages'>" +
|
|
1603
|
-
if (type == 'notice' || type == 'both')
|
|
1604
|
-
"<% if flash[:notice] -%><div id='notice' class='flash' onclick='new Effect.Fade(\"error\")'><%= flash[:notice] %></div><% end -%>"
|
|
1605
|
-
else
|
|
1606
|
-
''
|
|
1607
|
-
end +
|
|
1608
|
-
if (type == 'error' || type == 'both')
|
|
1609
|
-
"<% if flash[:error] -%><div id='error' class='flash' onclick='new Effect.Fade(\"error\")'><%= flash[:error] %></div><% end -%>"
|
|
1610
|
-
else
|
|
1611
|
-
''
|
|
1612
|
-
end +
|
|
1613
|
-
"</div>"
|
|
1614
|
-
end
|
|
1615
|
-
|
|
1616
|
-
# Shows a 'made with zena' link or logo. ;-) Thanks for using this !
|
|
1617
|
-
# TODO: test and add translation.
|
|
1618
|
-
# <r:zena show='logo'/> or <r:zena show='text'/> == <r:zena/>
|
|
1619
|
-
def r_zena
|
|
1620
|
-
if logo = @params[:logo]
|
|
1621
|
-
# FIXME
|
|
1622
|
-
case logo
|
|
1623
|
-
when 'tiny'
|
|
1624
|
-
else
|
|
1625
|
-
end
|
|
1626
|
-
else
|
|
1627
|
-
text = case @params[:type]
|
|
1628
|
-
when 'riding'
|
|
1629
|
-
_("riding zena")
|
|
1630
|
-
when 'peace'
|
|
1631
|
-
_("in peace with zena")
|
|
1632
|
-
when 'garden'
|
|
1633
|
-
_("a zen garden")
|
|
1634
|
-
else
|
|
1635
|
-
_("made with zena")
|
|
1636
|
-
end
|
|
1637
|
-
"<a class='zena' href='http://zenadmin.org' title='zena <%= Zena::VERSION %>'>#{text}</a>"
|
|
1638
|
-
end
|
|
1639
|
-
end
|
|
1640
|
-
|
|
1641
|
-
def r_design
|
|
1642
|
-
if @params[:by]
|
|
1643
|
-
by = "<a href='#{@params[:href]}'>#{@params[:by]}</a>"
|
|
1644
|
-
else
|
|
1645
|
-
by = expand_with(:trans => true)
|
|
1646
|
-
end
|
|
1647
|
-
unless skin = @params[:skin]
|
|
1648
|
-
skin = helper.instance_variable_get(:@controller).instance_variable_get(:@skin_name)
|
|
1649
|
-
end
|
|
1650
|
-
skin = "<i>#{skin}</i>" unless skin.blank?
|
|
1651
|
-
_("%{skin}, design by %{name}") % {:name => by, :skin => skin}
|
|
1652
|
-
end
|
|
1653
|
-
|
|
1654
|
-
# creates a link. Options are:
|
|
1655
|
-
# :href (node, parent, project, root)
|
|
1656
|
-
# :tattr (translated attribute used as text link)
|
|
1657
|
-
# :attr (attribute used as text link)
|
|
1658
|
-
# <r:link href='node'><r:trans attr='lang'/></r:link>
|
|
1659
|
-
# <r:link href='node' tattr='lang'/>
|
|
1660
|
-
# <r:link update='dom_id'/>
|
|
1661
|
-
# <r:link page='next'/> <r:link page='previous'/> <r:link page='list'/>
|
|
1662
|
-
def r_link
|
|
1663
|
-
if @params[:page]
|
|
1664
|
-
pagination_links
|
|
1665
|
-
else
|
|
1666
|
-
make_link
|
|
1667
|
-
end
|
|
1668
|
-
end
|
|
1669
|
-
|
|
1670
|
-
def make_link(options = {})
|
|
1671
|
-
query_params = options[:query_params] || {}
|
|
1672
|
-
default_text = options[:default_text]
|
|
1673
|
-
params = @params.dup
|
|
1674
|
-
|
|
1675
|
-
opts = {}
|
|
1676
|
-
if upd = params.delete(:update)
|
|
1677
|
-
return unless remote_target = find_target(upd)
|
|
1678
|
-
end
|
|
1679
|
-
|
|
1680
|
-
if href = params.delete(:href)
|
|
1681
|
-
if lnode = find_stored(Node, href)
|
|
1682
|
-
# using stored node
|
|
1683
|
-
else
|
|
1684
|
-
lnode, klass = build_finder_for(:first, href, {})
|
|
1685
|
-
return unless lnode
|
|
1686
|
-
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
|
1687
|
-
end
|
|
1688
|
-
else
|
|
1689
|
-
# obj
|
|
1690
|
-
if node_class == Version
|
|
1691
|
-
lnode = "#{node}.node"
|
|
1692
|
-
opts[:lang] = "#{node}.lang"
|
|
1693
|
-
elsif node_kind_of?(Node)
|
|
1694
|
-
lnode = node
|
|
1695
|
-
else
|
|
1696
|
-
lnode = @context[:previous_node]
|
|
1697
|
-
end
|
|
1698
|
-
end
|
|
1699
|
-
|
|
1700
|
-
if fmt = params.delete(:format)
|
|
1701
|
-
if fmt == 'data'
|
|
1702
|
-
opts[:format] = "#{node}.c_ext"
|
|
1703
|
-
else
|
|
1704
|
-
opts[:format] = fmt.inspect
|
|
1705
|
-
end
|
|
1706
|
-
end
|
|
1707
|
-
|
|
1708
|
-
if mode = params.delete(:mode)
|
|
1709
|
-
opts[:mode] = mode.inspect
|
|
1710
|
-
end
|
|
1711
|
-
|
|
1712
|
-
if sharp = params.delete(:sharp)
|
|
1713
|
-
opts[:sharp] = sharp.inspect
|
|
1714
|
-
end
|
|
1715
|
-
|
|
1716
|
-
if sharp_in = params.delete(:in)
|
|
1717
|
-
finder, klass = build_finder_for(:first, sharp_in, {})
|
|
1718
|
-
return unless finder
|
|
1719
|
-
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
|
1720
|
-
opts[:sharp_in] = finder
|
|
1721
|
-
end
|
|
1722
|
-
|
|
1723
|
-
if @html_tag && @html_tag != 'a'
|
|
1724
|
-
# FIXME: can we remove this ?
|
|
1725
|
-
# html attributes do not belong to anchor
|
|
1726
|
-
pre_space = ''
|
|
1727
|
-
html_params = {}
|
|
1728
|
-
else
|
|
1729
|
-
html_params = get_html_params(params.merge(@html_tag_params), :link)
|
|
1730
|
-
pre_space = @space_before || ''
|
|
1731
|
-
@html_tag_done = true
|
|
1732
|
-
end
|
|
1733
|
-
|
|
1734
|
-
(params.keys - [:style, :class, :id, :rel, :name, :anchor, :attr, :tattr, :trans, :text, :page]).each do |k|
|
|
1735
|
-
next if k.to_s =~ /if_|set_/
|
|
1736
|
-
query_params[k] = params[k]
|
|
1737
|
-
end
|
|
1738
|
-
|
|
1739
|
-
# TODO: merge these two query_params cleanup things into something cleaner.
|
|
1740
|
-
if remote_target
|
|
1741
|
-
# ajax
|
|
1742
|
-
query_params_list = []
|
|
1743
|
-
query_params.each do |k,v|
|
|
1744
|
-
if k == :date
|
|
1745
|
-
if v == 'current_date'
|
|
1746
|
-
str = "\#{#{current_date}}"
|
|
1747
|
-
elsif v =~ /\A\d/
|
|
1748
|
-
str = CGI.escape(v.gsub('"',''))
|
|
1749
|
-
elsif v =~ /\[/
|
|
1750
|
-
attribute, static = parse_attributes_in_value(v.gsub('"',''), :erb => false)
|
|
1751
|
-
str = static ? CGI.escape(attribute) : "\#{CGI.escape(\"#{attribute}\")}"
|
|
1752
|
-
else
|
|
1753
|
-
str = "\#{CGI.escape(#{node_attribute(v)})}"
|
|
1754
|
-
end
|
|
1755
|
-
else
|
|
1756
|
-
attribute, static = parse_attributes_in_value(v.gsub('"',''), :erb => false)
|
|
1757
|
-
str = static ? CGI.escape(attribute) : "\#{CGI.escape(\"#{attribute}\")}"
|
|
1758
|
-
end
|
|
1759
|
-
query_params_list << "#{k.to_s.gsub('"','')}=#{str}"
|
|
1760
|
-
end
|
|
1761
|
-
pre_space + link_to_update(remote_target, :node_id => "#{lnode}.zip", :query_params => query_params_list, :default_text => default_text, :html_params => html_params)
|
|
1762
|
-
else
|
|
1763
|
-
# direct link
|
|
1764
|
-
query_params.each do |k,v|
|
|
1765
|
-
if k == :date
|
|
1766
|
-
if v == 'current_date'
|
|
1767
|
-
query_params[k] = current_date
|
|
1768
|
-
elsif v =~ /\A\d/
|
|
1769
|
-
query_params[k] = v.inspect
|
|
1770
|
-
elsif v =~ /\[/
|
|
1771
|
-
attribute, static = parse_attributes_in_value(v.gsub('"',''), :erb => false)
|
|
1772
|
-
query_params[k] = "\"#{attribute}\""
|
|
1773
|
-
else
|
|
1774
|
-
query_params[k] = node_attribute(v)
|
|
1775
|
-
end
|
|
1776
|
-
else
|
|
1777
|
-
attribute, static = parse_attributes_in_value(v.gsub('"',''), :erb => false)
|
|
1778
|
-
query_params[k] = "\"#{attribute}\""
|
|
1779
|
-
end
|
|
1780
|
-
end
|
|
1781
|
-
|
|
1782
|
-
query_params.merge!(opts)
|
|
1783
|
-
|
|
1784
|
-
opts_str = ''
|
|
1785
|
-
query_params.keys.sort {|a,b| a.to_s <=> b.to_s }.each do |k|
|
|
1786
|
-
opts_str << ",:#{k.to_s.gsub(/[^a-z_A-Z_]/,'')}=>#{query_params[k]}"
|
|
1787
|
-
end
|
|
1788
|
-
|
|
1789
|
-
opts_str += ", :host => #{@context["exp_host"]}" if @context["exp_host"]
|
|
1790
|
-
|
|
1791
|
-
pre_space + "<a#{params_to_html(html_params)} href='<%= zen_path(#{lnode}#{opts_str}) %>'>#{text_for_link(default_text)}</a>"
|
|
1792
|
-
end
|
|
1793
|
-
end
|
|
1794
|
-
|
|
1795
|
-
# <r:link page='next'/> <r:link page='previous'/> <r:link page='list'/>
|
|
1796
|
-
def pagination_links
|
|
1797
|
-
return parser_error("not in pagination scope") unless pagination_key = @context[:paginate]
|
|
1798
|
-
case @params[:page]
|
|
1799
|
-
when 'previous'
|
|
1800
|
-
out "<% if set_#{pagination_key}_previous = (set_#{pagination_key} > 1 ? set_#{pagination_key} - 1 : nil) -%>"
|
|
1801
|
-
@context[:vars] ||= []
|
|
1802
|
-
@context[:vars] << "#{pagination_key}_previous"
|
|
1803
|
-
out make_link(:default_text => "<%= set_#{pagination_key}_previous %>", :query_params => {pagination_key => "[#{pagination_key}_previous]"})
|
|
1804
|
-
if descendant('else')
|
|
1805
|
-
out expand_with(:in_if => true, :only => ['else', 'elsif'])
|
|
1806
|
-
end
|
|
1807
|
-
out "<% end -%>"
|
|
1808
|
-
when 'next'
|
|
1809
|
-
out "<% if set_#{pagination_key}_next = (set_#{pagination_key}_count - set_#{pagination_key} > 0 ? set_#{pagination_key} + 1 : nil) -%>"
|
|
1810
|
-
@context[:vars] ||= []
|
|
1811
|
-
@context[:vars] << "#{pagination_key}_next"
|
|
1812
|
-
out make_link(:default_text => "<%= set_#{pagination_key}_next %>", :query_params => {pagination_key => "[#{pagination_key}_next]"})
|
|
1813
|
-
if descendant('else')
|
|
1814
|
-
out expand_with(:in_if => true, :only => ['else', 'elsif'])
|
|
1815
|
-
end
|
|
1816
|
-
out "<% end -%>"
|
|
1817
|
-
when 'list'
|
|
1818
|
-
@context[:vars] ||= []
|
|
1819
|
-
@context[:vars] << "#{pagination_key}_page"
|
|
1820
|
-
if @blocks == [] || (@blocks.size == 1 && !@blocks.first.kind_of?(String) && @blocks.first.method == 'else')
|
|
1821
|
-
# add a default block
|
|
1822
|
-
if tag = @params[:tag]
|
|
1823
|
-
open_tag = "<#{tag}>"
|
|
1824
|
-
close_tag = "</#{tag}>"
|
|
1825
|
-
else
|
|
1826
|
-
open_tag = close_tag = ''
|
|
1827
|
-
end
|
|
1828
|
-
link_params = {}
|
|
1829
|
-
@params.each do |k,v|
|
|
1830
|
-
next if [:tag, :page, :join, :page_count].include?(k)
|
|
1831
|
-
link_params[k] = v
|
|
1832
|
-
end
|
|
1833
|
-
text = "#{open_tag}<r:link #{params_to_html(link_params)} #{pagination_key}='[#{pagination_key}_page]' do='[#{pagination_key}_page]'/>#{close_tag}"
|
|
1834
|
-
@blocks = [make(:void, :method=>'void', :text=>text)]
|
|
1835
|
-
remove_instance_variable(:@all_descendants)
|
|
1836
|
-
end
|
|
1837
|
-
|
|
1838
|
-
if !descendant('else')
|
|
1839
|
-
@blocks += [make(:void, :method=>'void', :text=>"<r:else>#{open_tag}<r:show var='#{pagination_key}_page'/>#{close_tag}</r:else>")]
|
|
1840
|
-
remove_instance_variable(:@all_descendants)
|
|
1841
|
-
end
|
|
1842
|
-
|
|
1843
|
-
out "<% page_numbers(set_#{pagination_key}, set_#{pagination_key}_count, #{(@params[:join] || ' ').inspect}, #{@params[:page_count] ? @params[:page_count].to_i : 'nil'}) do |set_#{pagination_key}_page, #{pagination_key}_page_join| %>"
|
|
1844
|
-
out "<%= #{pagination_key}_page_join %>"
|
|
1845
|
-
out "<% if set_#{pagination_key}_page != set_#{pagination_key} -%>"
|
|
1846
|
-
out expand_with(:in_if => true)
|
|
1847
|
-
out "<% end; end -%>"
|
|
1848
|
-
else
|
|
1849
|
-
parser_error("unkown 'page' option #{@params[:page].inspect} should be ('previous', 'next' or 'list')")
|
|
1850
|
-
end
|
|
1851
|
-
end
|
|
1852
|
-
|
|
1853
|
-
def r_img
|
|
1854
|
-
return unless node_kind_of?(Node)
|
|
1855
|
-
if @params[:src]
|
|
1856
|
-
finder, klass = build_finder_for(:first, @params[:src])
|
|
1857
|
-
return unless finder
|
|
1858
|
-
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
|
1859
|
-
img = finder
|
|
1860
|
-
else
|
|
1861
|
-
img = node
|
|
1862
|
-
end
|
|
1863
|
-
mode = @params[:mode] || 'std'
|
|
1864
|
-
# FIXME: replace this call by something that integrates better with html_tag_params and such.
|
|
1865
|
-
res = "img_tag(#{img}, :mode=>#{mode.inspect}"
|
|
1866
|
-
[:class, :alt_src, :id, :border, :style].each do |k|
|
|
1867
|
-
res += ", :#{k}=>#{@params[k].inspect}" if @params[k]
|
|
1868
|
-
end
|
|
1869
|
-
res += ", :host => #{@context["exp_host"]}" if @context["exp_host"]
|
|
1870
|
-
res += ")"
|
|
1871
|
-
if @params[:link]
|
|
1872
|
-
finder, klass = build_finder_for(:first, @params[:link])
|
|
1873
|
-
return unless finder
|
|
1874
|
-
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
|
1875
|
-
|
|
1876
|
-
opts_str = @context["exp_host"] ? ", :host => #{@context["exp_host"]}" : ""
|
|
1877
|
-
|
|
1878
|
-
"<a href='<%= zen_path(#{finder}#{opts_str}) %>'><%= #{res} %></a>"
|
|
1879
|
-
else
|
|
1880
|
-
"<%= #{res} %>"
|
|
1881
|
-
end
|
|
1882
|
-
end
|
|
1883
|
-
|
|
1884
|
-
def r_calendar
|
|
1885
|
-
if @context[:block] == self
|
|
1886
|
-
# called from self (storing template / rendering)
|
|
1887
|
-
if role = @params[:assign_as]
|
|
1888
|
-
assign_calendar(role)
|
|
1889
|
-
else
|
|
1890
|
-
display_calendar
|
|
1891
|
-
end
|
|
1892
|
-
else
|
|
1893
|
-
# This is called first to prepare calendar
|
|
1894
|
-
if @params[:assign_as]
|
|
1895
|
-
fld = 'date'
|
|
1896
|
-
table_name = 'links'
|
|
1897
|
-
else
|
|
1898
|
-
fld = @params[:date] || 'event_at'
|
|
1899
|
-
if ['log_at', 'created_at', 'updated_at', 'event_at'].include?(fld) # TODO: use rubyless to learn type
|
|
1900
|
-
table_name = 'nodes'
|
|
1901
|
-
elsif fld == 'l_date'
|
|
1902
|
-
fld = 'date'
|
|
1903
|
-
table_name = 'links'
|
|
1904
|
-
else
|
|
1905
|
-
return parser_error("Invalid 'date' value for calendar (#{fld.inspect}).")
|
|
1906
|
-
end
|
|
1907
|
-
end
|
|
1908
|
-
|
|
1909
|
-
@date_scope = "TABLE_NAME[#{table_name}].#{fld} >= '\#{start_date.strftime('%Y-%m-%d')}' AND TABLE_NAME[#{table_name}].#{fld} <= '\#{end_date.strftime('%Y-%m-%d')}'"
|
|
1910
|
-
|
|
1911
|
-
new_dom_scope
|
|
1912
|
-
|
|
1913
|
-
# SAVED TEMPLATE
|
|
1914
|
-
template = expand_block(self, :block => self, :saved_template => true)
|
|
1915
|
-
out helper.save_erb_to_url(template, template_url)
|
|
1916
|
-
|
|
1917
|
-
# INLINE
|
|
1918
|
-
out expand_block(self, :block => self, :saved_template => false)
|
|
1919
|
-
end
|
|
1920
|
-
end
|
|
1921
|
-
|
|
1922
|
-
def display_calendar
|
|
1923
|
-
size = (params[:size] || 'large').to_sym
|
|
1924
|
-
finder = params[:select] || 'notes in project'
|
|
1925
|
-
|
|
1926
|
-
if @blocks == []
|
|
1927
|
-
# add a default <r:link/> block
|
|
1928
|
-
if size == :tiny
|
|
1929
|
-
@blocks = [make(:void, :method=>'void', :text=>"<em do='link' date='current_date' do='[current_date]' format='%d'/><r:else do='[current_date]' format='%d'/>")]
|
|
1930
|
-
else
|
|
1931
|
-
@blocks = [make(:void, :method=>'void', :text=>"<span do='show' date='current_date' format='%d'/><ul><li do='each' do='link' attr='name'/></ul><r:else do='[current_date]' format='%d'/>")]
|
|
1932
|
-
end
|
|
1933
|
-
remove_instance_variable(:@all_descendants)
|
|
1934
|
-
elsif !descendant('else')
|
|
1935
|
-
@blocks += [make(:void, :method=>'void', :text=>"<r:else do='[current_date]' format='%d'/>")]
|
|
1936
|
-
remove_instance_variable(:@all_descendants)
|
|
1937
|
-
end
|
|
1938
|
-
|
|
1939
|
-
@html_tag_done = false
|
|
1940
|
-
@html_tag_params[:id] = erb_dom_id
|
|
1941
|
-
@html_tag_params[:class] ||= "#{size}cal"
|
|
1942
|
-
@html_tag ||= 'div'
|
|
1943
|
-
|
|
1944
|
-
finder, klass = build_finder_for(:all, finder, @params, [@date_scope])
|
|
1945
|
-
return unless finder
|
|
1946
|
-
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
|
1947
|
-
|
|
1948
|
-
cell_code = "<% if #{list_var} = nodes_#{list_var}[cal_#{list_var}.strftime('%Y-%m-%d %H')] -%>#{expand_with(:in_if => true, :list => list_var, :date => "cal_#{list_var}", :saved_template => nil, :dom_prefix => nil, :in_calendar => true)}<% end -%>"
|
|
1949
|
-
|
|
1950
|
-
render_html_tag(calendar_code(finder, "", cell_code, "", params))
|
|
1951
|
-
end
|
|
1952
|
-
|
|
1953
|
-
# manage links from @node ---- reference ----> ...
|
|
1954
|
-
# <div do='calendar' assign='reference' to='main' split_hours='12' />
|
|
1955
|
-
def assign_calendar(as_role)
|
|
1956
|
-
size = (params[:size] || 'large').to_sym
|
|
1957
|
-
@html_tag_done = false
|
|
1958
|
-
@html_tag_params[:id] = erb_dom_id
|
|
1959
|
-
@html_tag_params[:class] ||= "#{size}cal"
|
|
1960
|
-
@html_tag ||= 'div'
|
|
1961
|
-
if rel = RelationProxy.find_by_role(as_role.singularize)
|
|
1962
|
-
role = rel.this_role
|
|
1963
|
-
else
|
|
1964
|
-
return parser_error("Invalid role #{as_role.inspect}.")
|
|
1965
|
-
end
|
|
1966
|
-
finder, klass = build_finder_for(:all, role, @params, [@date_scope])
|
|
1967
|
-
return unless finder
|
|
1968
|
-
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
|
1969
|
-
|
|
1970
|
-
# SAVED TEMPLATE ========
|
|
1971
|
-
template_url = self.template_url + 'cell'
|
|
1972
|
-
template = "<%= cal_assign_cell(@node, #{role.inspect}, #{@params[:used].inspect}) %>"
|
|
1973
|
-
out helper.save_erb_to_url(template, template_url)
|
|
1974
|
-
|
|
1975
|
-
# we call update on node 'B'
|
|
1976
|
-
# A (main)
|
|
1977
|
-
# ... B (other node)
|
|
1978
|
-
# calendar (in B context) ---- role --->
|
|
1979
|
-
|
|
1980
|
-
cell_prefix_code = "<span><%= day_#{list_var}.strftime('%d').to_i -%></span><ul>"
|
|
1981
|
-
cell_code = "<%= #{list_var} = nodes_#{list_var}[cal_#{list_var}.strftime('%Y-%m-%d %H')]; #{node}.linked_node = #{list_var} ? #{list_var}.first : nil; cal_assign_cell(#{node}, #{role.inspect}, #{@params[:used].inspect}, params[:s] || @node.zip, cal_#{list_var}, #{template_url.inspect}) %>"
|
|
1982
|
-
cell_postfix_code = "</ul>"
|
|
1983
|
-
render_html_tag(calendar_code(finder, cell_prefix_code, cell_code, cell_postfix_code, params))
|
|
1984
|
-
end
|
|
1985
|
-
|
|
1986
|
-
def calendar_code(finder, cell_prefix_code, cell_code, cell_postfix_code, params)
|
|
1987
|
-
type = params[:type] ? params[:type].to_sym : :month
|
|
1988
|
-
size = (params[:size] || 'large').to_sym
|
|
1989
|
-
ref_date = params[:assign_as] ? 'l_date' : (params[:date] || 'event_at')
|
|
1990
|
-
|
|
1991
|
-
case type
|
|
1992
|
-
when :month
|
|
1993
|
-
title = "\"\#{_(Date::MONTHNAMES[main_date.mon])} \#{main_date.year}\""
|
|
1994
|
-
prev_date = "\#{main_date.advance(:months => -1).strftime(\"%Y-%m-%d\")}"
|
|
1995
|
-
next_date = "\#{main_date.advance(:months => 1).strftime(\"%Y-%m-%d\")}"
|
|
1996
|
-
when :week
|
|
1997
|
-
title = "\"\#{_(Date::MONTHNAMES[main_date.mon])} \#{main_date.year}\""
|
|
1998
|
-
prev_date = "\#{main_date.advance(:days => -7).strftime(\"%Y-%m-%d\")}"
|
|
1999
|
-
next_date = "\#{main_date.advance(:days => +7).strftime(\"%Y-%m-%d\")}"
|
|
2000
|
-
else
|
|
2001
|
-
return parser_error("invalid type (should be 'month' or 'week')")
|
|
2002
|
-
end
|
|
2003
|
-
|
|
2004
|
-
if hours = @params[:split_hours]
|
|
2005
|
-
hours = hours.split(',').map{|l| l.to_i}
|
|
2006
|
-
hours << 0
|
|
2007
|
-
hours = hours.uniq.sort
|
|
2008
|
-
# I feel all this would be much better if we could use "each_group" but then how do we access hours ?
|
|
2009
|
-
week_code = "<% week.step(week+6,1) do |day_#{list_var}| -%>
|
|
2010
|
-
<td<%= cal_class(day_#{list_var},#{current_date}) %>>#{cell_prefix_code}<% #{hours.inspect}.each do |set_hour|; cal_#{list_var} = Time.utc(day_#{list_var}.year,day_#{list_var}.month,day_#{list_var}.day,set_hour) -%>#{cell_code}<% end -%>#{cell_postfix_code}</td>
|
|
2011
|
-
<% end -%>"
|
|
2012
|
-
(@context[:vars] ||= []) << "hour"
|
|
2013
|
-
else
|
|
2014
|
-
hours = nil
|
|
2015
|
-
week_code = "<% week.step(week+6,1) do |day_#{list_var}| -%>
|
|
2016
|
-
<td<%= cal_class(day_#{list_var},#{current_date}) %>><% cal_#{list_var} = Time.utc(day_#{list_var}.year,day_#{list_var}.month,day_#{list_var}.day) -%>#{cell_prefix_code}#{cell_code}#{cell_postfix_code}</td>
|
|
2017
|
-
<% end -%>"
|
|
2018
|
-
end
|
|
2019
|
-
|
|
2020
|
-
res = <<-END_TXT
|
|
2021
|
-
<h3 class='title'>
|
|
2022
|
-
<span><%= link_to_remote(#{_('img_prev_page').inspect}, :url => #{base_class.to_s.underscore}_path(#{node_id}) + \"/zafu?t_url=#{CGI.escape(template_url)}&dom_id=#{dom_id}&date=#{prev_date}&#{start_node_s_param(:string)}\", :method => :get) %></span>
|
|
2023
|
-
<span class='date'><%= link_to_remote(#{title}, :url => #{base_class.to_s.underscore}_path(#{node_id}) + \"/zafu?t_url=#{CGI.escape(template_url)}&dom_id=#{dom_id}&#{start_node_s_param(:string)}\", :method => :get) %></span>
|
|
2024
|
-
<span><%= link_to_remote(#{_('img_next_page').inspect}, :url => #{base_class.to_s.underscore}_path(#{node_id}) + \"/zafu?t_url=#{CGI.escape(template_url)}&dom_id=#{dom_id}&date=#{next_date}&#{start_node_s_param(:string)}\", :method => :get) %></span>
|
|
2025
|
-
</h3>
|
|
2026
|
-
<table cellspacing='0' class='#{size}cal#{@params[:assign_as] ? " assign" : ''}'>
|
|
2027
|
-
<tr class='head'><%= cal_day_names(#{size.inspect}) %></tr>
|
|
2028
|
-
<% start_date, end_date = cal_start_end(#{current_date}, #{type.inspect}) -%>
|
|
2029
|
-
<% cal_weeks(#{ref_date.to_sym.inspect}, #{finder}, start_date, end_date, #{hours.inspect}) do |week, nodes_#{list_var}| -%>
|
|
2030
|
-
<tr class='body'>
|
|
2031
|
-
#{week_code}
|
|
2032
|
-
</tr>
|
|
2033
|
-
<% end -%>
|
|
2034
|
-
</table>
|
|
2035
|
-
END_TXT
|
|
2036
|
-
end
|
|
2037
|
-
|
|
2038
|
-
# part caching
|
|
2039
|
-
def r_cache
|
|
2040
|
-
kpath = @params[:kpath] || Page.kpath
|
|
2041
|
-
out "<% #{cache} = Cache.with(visitor.id, visitor.group_ids, #{kpath.inspect}, #{helper.send(:lang).inspect}, #{template_url.inspect}) do capture do %>"
|
|
2042
|
-
out expand_with
|
|
2043
|
-
out "<% end; end %><%= #{cache} %>"
|
|
2044
|
-
end
|
|
2045
|
-
|
|
2046
|
-
# recursion
|
|
2047
|
-
def r_include
|
|
2048
|
-
return '' if @context[:saved_template]
|
|
2049
|
-
return super if @params[:template] || !@params[:part]
|
|
2050
|
-
part = @params[:part].gsub(/[^a-zA-Z_]/,'')
|
|
2051
|
-
method_name = @context["#{part}_method".to_sym]
|
|
2052
|
-
return parser_error("no parent named '#{part}'") unless method_name
|
|
2053
|
-
"<%= #{method_name}(depth+1,#{node},#{list}) %>"
|
|
2054
|
-
end
|
|
2055
|
-
|
|
2056
|
-
# use all other tags as relations
|
|
2057
|
-
def r_unknown
|
|
2058
|
-
@params[:select] = @method
|
|
2059
|
-
r_context
|
|
2060
|
-
end
|
|
2061
|
-
|
|
2062
|
-
# Enter a new context (<r:context find='all' method='pages'>). This is the same as '<r:pages>...</r:pages>'). It is
|
|
2063
|
-
# considered better style to use '<r:pages>...</r:pages>' instead of the more general '<r:context>' because the tags
|
|
2064
|
-
# give a clue on the context at start and end. Another way to open a context is the 'do' syntax: "<div do='pages'>...</div>".
|
|
2065
|
-
# FIXME: 'else' clause has been removed, find a solution to put it back.
|
|
2066
|
-
def r_context
|
|
2067
|
-
# DRY ! (build_finder_for, block)
|
|
2068
|
-
return parser_error("missing 'method' parameter") unless method = @params[:select]
|
|
2069
|
-
|
|
2070
|
-
context = node_class.zafu_known_contexts[method]
|
|
2071
|
-
if context && @params.keys == [:select]
|
|
2072
|
-
open_context("#{node}.#{method}", context)
|
|
2073
|
-
elsif node_kind_of?(Node)
|
|
2074
|
-
count = ['first','all','count'].include?(@params[:find]) ? @params[:find].to_sym : nil
|
|
2075
|
-
count ||= Node.plural_relation?(method) ? :all : :first
|
|
2076
|
-
finder, klass, query = build_finder_for(count, method, @params)
|
|
2077
|
-
return unless finder
|
|
2078
|
-
if node_kind_of?(Node) && !klass.ancestors.include?(Node)
|
|
2079
|
-
# moving out of node: store last Node
|
|
2080
|
-
@context[:previous_node] = node
|
|
2081
|
-
end
|
|
2082
|
-
if count == :all
|
|
2083
|
-
# plural
|
|
2084
|
-
do_list( finder, query, :node_class => klass)
|
|
2085
|
-
# elsif count == :count
|
|
2086
|
-
# "<%= #{build_finder_for(count, method, @params)} %>"
|
|
2087
|
-
else
|
|
2088
|
-
# singular
|
|
2089
|
-
do_var( finder, :node_class => klass)
|
|
2090
|
-
end
|
|
2091
|
-
else
|
|
2092
|
-
"unknown relation (#{method}) for #{node_class} class"
|
|
2093
|
-
end
|
|
2094
|
-
end
|
|
2095
|
-
|
|
2096
|
-
def open_context(finder, context)
|
|
2097
|
-
klass = context[:node_class]
|
|
2098
|
-
# hack to store last 'Node' context until we fix node(Node) stuff:
|
|
2099
|
-
previous_node = node_kind_of?(Node) ? node : @context[:previous_node]
|
|
2100
|
-
if klass.kind_of?(Array)
|
|
2101
|
-
# plural
|
|
2102
|
-
do_list( finder, nil, context.merge(:node_class => klass[0], :previous_node => previous_node) )
|
|
2103
|
-
else
|
|
2104
|
-
# singular
|
|
2105
|
-
do_var( finder, context.merge(:previous_node => previous_node) )
|
|
2106
|
-
end
|
|
2107
|
-
end
|
|
2108
|
-
|
|
2109
|
-
# Prepare stylesheet and xml content for xsl-fo post-processor
|
|
2110
|
-
def r_fop
|
|
2111
|
-
return parser_error("missing 'stylesheet' argument") unless @params[:stylesheet]
|
|
2112
|
-
# get stylesheet text
|
|
2113
|
-
xsl_content, absolute_url, doc = self.class.get_template_text(@params[:stylesheet], @options[:helper], @options[:current_folder])
|
|
2114
|
-
return parser_error("stylesheet #{@params[:stylesheet].inspect} not found") unless doc
|
|
2115
|
-
|
|
2116
|
-
template_url = (self.template_url.split('/')[0..-2] + ['_main.xsl']).join('/')
|
|
2117
|
-
helper.save_erb_to_url(xsl_content, template_url)
|
|
2118
|
-
out "<?xml version='1.0' encoding='utf-8'?>\n"
|
|
2119
|
-
out "<!-- xsl_id:#{doc[:id] } -->\n" if doc
|
|
2120
|
-
out expand_with
|
|
2121
|
-
end
|
|
2122
|
-
|
|
2123
|
-
# Prepare content for LateX post-processor
|
|
2124
|
-
def r_latex
|
|
2125
|
-
out "% latex\n"
|
|
2126
|
-
# all content inside this will be informed to render for Latex output
|
|
2127
|
-
out expand_with(:output_format => 'latex')
|
|
2128
|
-
end
|
|
2129
|
-
|
|
2130
|
-
def r_debug
|
|
2131
|
-
return '' unless @context[:dev]
|
|
2132
|
-
add_html_class('debug')
|
|
2133
|
-
out "<p>#{@params[:title]}</p>" if @params[:title]
|
|
2134
|
-
(@params[:show] || '').split(',').map(&:strip).each do |what|
|
|
2135
|
-
case what
|
|
2136
|
-
when 'params'
|
|
2137
|
-
out "<pre><%= params.inspect %></pre>"
|
|
2138
|
-
else
|
|
2139
|
-
parser_error("invalid element to show. Options are ['params'].")
|
|
2140
|
-
end
|
|
2141
|
-
end
|
|
2142
|
-
out expand_with
|
|
2143
|
-
end
|
|
2144
|
-
|
|
2145
|
-
# ================== HELPER METHODS ================
|
|
2146
|
-
|
|
2147
|
-
# Create an sql query to open a new context (passes its arguments to HasRelations#build_find)
|
|
2148
|
-
def build_finder_for(count, rel, params=@params, raw_filters = [])
|
|
2149
|
-
if (context = node_class.zafu_known_contexts[rel]) && !params[:in] && !params[:where] && !params[:from] && !params[:order] && raw_filters == []
|
|
2150
|
-
klass = context[:node_class]
|
|
2151
|
-
|
|
2152
|
-
if klass.kind_of?(Array) && count == :all
|
|
2153
|
-
return ["#{node}.#{rel}", klass[0]]
|
|
2154
|
-
else
|
|
2155
|
-
return [(count == :all ? "[#{node}.#{rel}]" : "#{node}.#{rel}"), klass]
|
|
2156
|
-
end
|
|
2157
|
-
end
|
|
2158
|
-
|
|
2159
|
-
rel ||= 'self'
|
|
2160
|
-
if (count == :first)
|
|
2161
|
-
if rel == 'self'
|
|
2162
|
-
return [node, node_class]
|
|
2163
|
-
elsif rel == 'main'
|
|
2164
|
-
return ["@node", Node]
|
|
2165
|
-
elsif rel == 'root'
|
|
2166
|
-
return ["(secure(Node) { Node.find(#{current_site[:root_id]})})", Node]
|
|
2167
|
-
elsif rel == 'start'
|
|
2168
|
-
return ["start_node", Node]
|
|
2169
|
-
elsif rel == 'visitor'
|
|
2170
|
-
return ["visitor.contact", Node]
|
|
2171
|
-
elsif rel =~ /^\d+$/
|
|
2172
|
-
return ["(secure(Node) { Node.find_by_zip(#{rel.inspect})})", Node]
|
|
2173
|
-
elsif node_name = find_stored(Node, rel)
|
|
2174
|
-
return [node_name, Node]
|
|
2175
|
-
elsif rel[0..0] == '/'
|
|
2176
|
-
rel = rel[1..-1]
|
|
2177
|
-
return ["(secure(Node) { Node.find_by_path(#{rel.inspect})})", Node]
|
|
2178
|
-
end
|
|
2179
|
-
end
|
|
2180
|
-
|
|
2181
|
-
pseudo_sql, add_raw_filters = make_pseudo_sql(rel, params)
|
|
2182
|
-
raw_filters += add_raw_filters if add_raw_filters
|
|
2183
|
-
|
|
2184
|
-
# FIXME: stored should be clarified and managed in a single way through links and contexts.
|
|
2185
|
-
# <r:void store='foo'>...
|
|
2186
|
-
# <r:link href='foo'/>
|
|
2187
|
-
# <r:pages from='foo'/> <-- this is just a matter of changing node parameter
|
|
2188
|
-
# <r:pages from='site' project='foo'/>
|
|
2189
|
-
# <r:img link='foo'/>
|
|
2190
|
-
# ...
|
|
2191
|
-
|
|
2192
|
-
if node_kind_of?(Node)
|
|
2193
|
-
node_name = @context[:parent_node] || node
|
|
2194
|
-
else
|
|
2195
|
-
node_name = @context[:previous_node]
|
|
2196
|
-
end
|
|
2197
|
-
|
|
2198
|
-
# make sure we do not use a new record in a find query:
|
|
2199
|
-
query = Node.build_find(count, pseudo_sql, :node_name => node_name, :raw_filters => raw_filters, :ref_date => "\#{#{current_date}}")
|
|
2200
|
-
|
|
2201
|
-
unless query.valid?
|
|
2202
|
-
out parser_error(query.errors.join(' '), pseudo_sql.join(', '))
|
|
2203
|
-
return nil
|
|
2204
|
-
end
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
if count == :count
|
|
2208
|
-
out "<%= #{query.finder(:count)} %>"
|
|
2209
|
-
return nil
|
|
2210
|
-
end
|
|
2211
|
-
|
|
2212
|
-
klass = query.main_class
|
|
2213
|
-
|
|
2214
|
-
if params[:else]
|
|
2215
|
-
# FIXME: else not working with zafu_known_contexts
|
|
2216
|
-
finder, else_class, else_query = build_finder_for(count, params[:else], {})
|
|
2217
|
-
if finder && (else_query.nil? || else_query.valid?) && (else_class == klass || klass.ancestors.include?(else_class) || else_class.ancestors.include?(klass))
|
|
2218
|
-
["(#{query.finder(count)} || #{finder})", klass, query]
|
|
2219
|
-
else
|
|
2220
|
-
[query.finder(count), query.main_class, query]
|
|
2221
|
-
end
|
|
2222
|
-
else
|
|
2223
|
-
[query.finder(count), query.main_class, query]
|
|
2224
|
-
end
|
|
2225
|
-
end
|
|
2226
|
-
|
|
2227
|
-
# Build pseudo sql from the parameters
|
|
2228
|
-
# comments where ... from ... in ... order ... limit
|
|
2229
|
-
def make_pseudo_sql(rel, params=@params)
|
|
2230
|
-
parts = [rel.dup]
|
|
2231
|
-
filters = []
|
|
2232
|
-
|
|
2233
|
-
if params[:from]
|
|
2234
|
-
parts << params[:from]
|
|
2235
|
-
|
|
2236
|
-
key_counter = 1
|
|
2237
|
-
while sub_part = params["from#{key_counter}".to_sym]
|
|
2238
|
-
key_counter += 1
|
|
2239
|
-
parts << sub_part
|
|
2240
|
-
end
|
|
2241
|
-
end
|
|
2242
|
-
|
|
2243
|
-
if params[:where]
|
|
2244
|
-
parts[0] << " where #{params[:where]}"
|
|
2245
|
-
end
|
|
2246
|
-
|
|
2247
|
-
if params[:in]
|
|
2248
|
-
parts[-1] << " in #{params[:in]}"
|
|
2249
|
-
end
|
|
2250
|
-
|
|
2251
|
-
if group = params[:group]
|
|
2252
|
-
parts[-1] << " group by #{group}" unless parts[0] =~ /group by/
|
|
2253
|
-
end
|
|
2254
|
-
|
|
2255
|
-
if order = params[:order]
|
|
2256
|
-
parts[-1] << " order by #{order}" unless parts[0] =~ /order by/
|
|
2257
|
-
end
|
|
2258
|
-
|
|
2259
|
-
if paginate = params[:paginate]
|
|
2260
|
-
page_size = params[:limit].to_i
|
|
2261
|
-
page_size = 20 if page_size < 1
|
|
2262
|
-
parts[-1] << " limit #{page_size} paginate #{paginate.gsub(/[^a-z_A-Z]/,'')}"
|
|
2263
|
-
else
|
|
2264
|
-
[:limit, :offset].each do |k|
|
|
2265
|
-
next unless params[k]
|
|
2266
|
-
parts[-1] << " #{k} #{params[k]}" unless parts[0] =~ / #{k} /
|
|
2267
|
-
end
|
|
2268
|
-
end
|
|
2269
|
-
|
|
2270
|
-
finders = [parts.join(' from ')]
|
|
2271
|
-
if params[:or]
|
|
2272
|
-
finders << params[:or]
|
|
2273
|
-
|
|
2274
|
-
key_counter = 1
|
|
2275
|
-
while sub_or = params["or#{key_counter}".to_sym]
|
|
2276
|
-
key_counter += 1
|
|
2277
|
-
finders << sub_or
|
|
2278
|
-
end
|
|
2279
|
-
else
|
|
2280
|
-
or_clause = nil
|
|
2281
|
-
end
|
|
2282
|
-
|
|
2283
|
-
return [finders, parse_raw_filters(params)]
|
|
2284
|
-
end
|
|
2285
|
-
|
|
2286
|
-
# Parse special filters
|
|
2287
|
-
def parse_raw_filters(params)
|
|
2288
|
-
filters = []
|
|
2289
|
-
|
|
2290
|
-
if value = params[:author]
|
|
2291
|
-
if stored = find_stored(User, value)
|
|
2292
|
-
filters << "TABLE_NAME.user_id = '\#{#{stored}.id}'"
|
|
2293
|
-
elsif value == 'current'
|
|
2294
|
-
filters << "TABLE_NAME.user_id = '\#{#{node}[:user_id]}'"
|
|
2295
|
-
elsif value == 'visitor'
|
|
2296
|
-
filters << "TABLE_NAME.user_id = '\#{visitor[:id]}'"
|
|
2297
|
-
elsif value =~ /\A\d+\Z/
|
|
2298
|
-
filters << "TABLE_NAME.user_id = '#{value.to_i}'"
|
|
2299
|
-
elsif value =~ /\A[\w\/]+\Z/
|
|
2300
|
-
# TODO: path, not implemented yet
|
|
2301
|
-
end
|
|
2302
|
-
end
|
|
2303
|
-
|
|
2304
|
-
if value = params[:project]
|
|
2305
|
-
if stored = find_stored(Node, value)
|
|
2306
|
-
filters << "TABLE_NAME.project_id = '\#{#{stored}.get_project_id}'"
|
|
2307
|
-
elsif value == 'current'
|
|
2308
|
-
filters << "TABLE_NAME.project_id = '\#{#{node}.get_project_id}'"
|
|
2309
|
-
elsif value =~ /\A\d+\Z/
|
|
2310
|
-
filters << "TABLE_NAME.project_id = '#{value.to_i}'"
|
|
2311
|
-
elsif value =~ /\A[\w\/]+\Z/
|
|
2312
|
-
# TODO: path, not implemented yet
|
|
2313
|
-
end
|
|
2314
|
-
end
|
|
2315
|
-
|
|
2316
|
-
if value = params[:section]
|
|
2317
|
-
if stored = find_stored(Node, value)
|
|
2318
|
-
filters << "TABLE_NAME.section_id = '\#{#{stored}.get_section_id}'"
|
|
2319
|
-
elsif value == 'current'
|
|
2320
|
-
filters << "TABLE_NAME.section_id = '\#{#{node}.get_section_id}'"
|
|
2321
|
-
elsif value =~ /\A\d+\Z/
|
|
2322
|
-
filters << "TABLE_NAME.section_id = '#{value.to_i}'"
|
|
2323
|
-
elsif value =~ /\A[\w\/]+\Z/
|
|
2324
|
-
# not implemented yet
|
|
2325
|
-
end
|
|
2326
|
-
end
|
|
2327
|
-
|
|
2328
|
-
[:updated, :created, :event, :log].each do |k|
|
|
2329
|
-
if value = params[k]
|
|
2330
|
-
# current, same are synonym for 'today'
|
|
2331
|
-
filters << date_condition(value,"TABLE_NAME.#{k}_at",current_date)
|
|
2332
|
-
end
|
|
2333
|
-
end
|
|
2334
|
-
|
|
2335
|
-
filters == [] ? nil : filters
|
|
2336
|
-
end
|
|
2337
|
-
|
|
2338
|
-
# helpers
|
|
2339
|
-
# get current output format
|
|
2340
|
-
def output_format
|
|
2341
|
-
@context[:output_format] || 'html'
|
|
2342
|
-
end
|
|
2343
|
-
|
|
2344
|
-
# find the current node name in the context
|
|
2345
|
-
def node(klass = self.node_class)
|
|
2346
|
-
if klass == self.node_class
|
|
2347
|
-
(@context[:saved_template] && @context[:main_node]) ? "@#{base_class.to_s.underscore}" : (@context[:node] || '@node')
|
|
2348
|
-
elsif klass == Node
|
|
2349
|
-
@context[:previous_node] || '@node'
|
|
2350
|
-
else
|
|
2351
|
-
# ?
|
|
2352
|
-
out parser_error("could not find node_name for #{klass} (current class is #{node_class})")
|
|
2353
|
-
'@node'
|
|
2354
|
-
end
|
|
2355
|
-
end
|
|
2356
|
-
|
|
2357
|
-
def erb_node_id(obj = node)
|
|
2358
|
-
if node_kind_of?(Version)
|
|
2359
|
-
"<%= #{obj}.node.zip %>.<%= #{obj}.number %>"
|
|
2360
|
-
else
|
|
2361
|
-
"<%= #{node_id(obj)} %>"
|
|
2362
|
-
end
|
|
2363
|
-
end
|
|
2364
|
-
|
|
2365
|
-
def node_id(obj = node)
|
|
2366
|
-
"#{obj}.zip"
|
|
2367
|
-
end
|
|
2368
|
-
|
|
2369
|
-
def current_date
|
|
2370
|
-
@context[:date] || 'main_date'
|
|
2371
|
-
end
|
|
2372
|
-
|
|
2373
|
-
def var
|
|
2374
|
-
return @var if @var
|
|
2375
|
-
if node =~ /^var(\d+)$/
|
|
2376
|
-
@var = "var#{$1.to_i + 1}"
|
|
2377
|
-
else
|
|
2378
|
-
@var = "var1"
|
|
2379
|
-
end
|
|
2380
|
-
end
|
|
2381
|
-
|
|
2382
|
-
def cache
|
|
2383
|
-
return @cache if @cache
|
|
2384
|
-
if @context[:cache] =~ /^cache(\d+)$/
|
|
2385
|
-
@cache = "cache#{$1.to_i + 1}"
|
|
2386
|
-
else
|
|
2387
|
-
@cache = "cache1"
|
|
2388
|
-
end
|
|
2389
|
-
end
|
|
2390
|
-
|
|
2391
|
-
def list_var
|
|
2392
|
-
return @list_var if @list_var
|
|
2393
|
-
if (list || "") =~ /^list(\d+)$/
|
|
2394
|
-
@list_var = "list#{$1.to_i + 1}"
|
|
2395
|
-
else
|
|
2396
|
-
@list_var = "list1"
|
|
2397
|
-
end
|
|
2398
|
-
end
|
|
2399
|
-
|
|
2400
|
-
# Class of the current 'node' object (can be Version, Comment, Node, DataEntry, etc)
|
|
2401
|
-
def node_class
|
|
2402
|
-
@context[:node_class] || Node
|
|
2403
|
-
end
|
|
2404
|
-
|
|
2405
|
-
def base_class
|
|
2406
|
-
if node_kind_of?(Node)
|
|
2407
|
-
Node
|
|
2408
|
-
elsif node_kind_of?(Version)
|
|
2409
|
-
Version
|
|
2410
|
-
else
|
|
2411
|
-
node_class
|
|
2412
|
-
end
|
|
2413
|
-
end
|
|
2414
|
-
|
|
2415
|
-
def node_kind_of?(ancestor)
|
|
2416
|
-
node_class.ancestors.include?(ancestor)
|
|
2417
|
-
end
|
|
2418
|
-
|
|
2419
|
-
def list
|
|
2420
|
-
@context[:list]
|
|
2421
|
-
end
|
|
2422
|
-
|
|
2423
|
-
def helper
|
|
2424
|
-
@options[:helper]
|
|
2425
|
-
end
|
|
2426
|
-
|
|
2427
|
-
def params_to_erb(params, initial_comma = true)
|
|
2428
|
-
res = initial_comma ? [""] : []
|
|
2429
|
-
params.each do |k,v|
|
|
2430
|
-
if v =~ /<%=/ && !(v =~ /"/)
|
|
2431
|
-
# replace by #{}
|
|
2432
|
-
val = v.gsub('#{', '# {').gsub(/<%=(.*?)%>/,'#{\1}')
|
|
2433
|
-
res << "#{k.inspect}=>\"#{val}\""
|
|
2434
|
-
else
|
|
2435
|
-
res << "#{k.inspect}=>#{v.inspect}"
|
|
2436
|
-
end
|
|
2437
|
-
end
|
|
2438
|
-
res.join(', ')
|
|
2439
|
-
end
|
|
2440
|
-
|
|
2441
|
-
def do_var(var_finder=nil, opts={})
|
|
2442
|
-
clear_dom_scope
|
|
2443
|
-
if var_finder == 'nil'
|
|
2444
|
-
out "<% if nil -%>"
|
|
2445
|
-
elsif var_finder
|
|
2446
|
-
out "<% if #{var} = #{var_finder} -%>"
|
|
2447
|
-
end
|
|
2448
|
-
|
|
2449
|
-
if descendant('unlink')
|
|
2450
|
-
@html_tag ||= 'div'
|
|
2451
|
-
new_dom_scope
|
|
2452
|
-
@html_tag_params[:id] = erb_dom_id
|
|
2453
|
-
end
|
|
2454
|
-
|
|
2455
|
-
res = expand_with(opts.merge(:node=>var, :in_if => false))
|
|
2456
|
-
|
|
2457
|
-
if var_finder
|
|
2458
|
-
res += expand_with(opts.merge(:in_if => true, :only => ['else', 'elsif'], :html_tag_params => @html_tag_params, :html_tag => @html_tag))
|
|
2459
|
-
end
|
|
2460
|
-
out render_html_tag(res)
|
|
2461
|
-
out "<% end -%>" if var_finder
|
|
2462
|
-
end
|
|
2463
|
-
|
|
2464
|
-
def do_list(list_finder, query = nil, opts={})
|
|
2465
|
-
clear_dom_scope
|
|
2466
|
-
|
|
2467
|
-
@context.merge!(opts) # pass options from 'zafu_known_contexts' to @context
|
|
2468
|
-
|
|
2469
|
-
if (each_block = descendant('each')) && (each_block.descendant('edit') || descendant('add') || descendant('add_document') || (descendant('swap') && descendant('swap').parent.method != 'block') || ['block', 'drop'].include?(each_block.single_child_method))
|
|
2470
|
-
new_dom_scope
|
|
2471
|
-
# ajax, build template. We could merge the following code with 'r_block'.
|
|
2472
|
-
add_block = descendant('add')
|
|
2473
|
-
form_block = descendant('form') || each_block
|
|
2474
|
-
|
|
2475
|
-
@context[:need_link_id] = form_block.need_link_id
|
|
2476
|
-
|
|
2477
|
-
out "<% if (#{list_var} = #{list_finder}) || (#{node}.#{node_kind_of?(Comment) ? "can_comment?" : "can_write?"} && #{list_var}=[]) -%>"
|
|
2478
|
-
if query && (pagination_key = query.pagination_key)
|
|
2479
|
-
out "<% set_#{pagination_key}_nodes = #{query.finder(:count)}; set_#{pagination_key}_count = (set_#{pagination_key}_nodes / #{query.page_size.to_f}).ceil; set_#{pagination_key} = [1,params[:#{pagination_key}].to_i].max -%>"
|
|
2480
|
-
@context[:paginate] = pagination_key
|
|
2481
|
-
@context[:vars] ||= []
|
|
2482
|
-
@context[:vars] << "#{pagination_key}_nodes"
|
|
2483
|
-
@context[:vars] << "#{pagination_key}_count"
|
|
2484
|
-
@context[:vars] << "#{pagination_key}"
|
|
2485
|
-
end
|
|
2486
|
-
|
|
2487
|
-
# should we publish ?
|
|
2488
|
-
publish_after_save ||= form_block ? form_block.params[:publish] : nil
|
|
2489
|
-
publish_after_save ||= descendant('edit') ? descendant('edit').params[:publish] : nil
|
|
2490
|
-
|
|
2491
|
-
# class name for create form
|
|
2492
|
-
klass = add_block ? add_block.params[:klass] : nil
|
|
2493
|
-
klass ||= form_block ? form_block.params[:klass] : nil
|
|
2494
|
-
|
|
2495
|
-
# INLINE ==========
|
|
2496
|
-
# 'r_add' needs the form when rendering. Send with :form.
|
|
2497
|
-
out render_html_tag(expand_with(:list=>list_var, :in_if => false, :form=>form_block, :publish_after_save => publish_after_save, :ignore => ['form'], :klass => klass))
|
|
2498
|
-
out expand_with(:in_if=>true, :only=>['elsif', 'else'], :html_tag => @html_tag, :html_tag_params => @html_tag_params)
|
|
2499
|
-
out "<% end -%>"
|
|
2500
|
-
|
|
2501
|
-
# SAVED TEMPLATE ========
|
|
2502
|
-
template = expand_block(each_block, :list=>false, :klass => klass, :saved_template => true)
|
|
2503
|
-
out helper.save_erb_to_url(template, template_url)
|
|
2504
|
-
|
|
2505
|
-
# FORM ============
|
|
2506
|
-
if each_block != form_block
|
|
2507
|
-
form = expand_block(form_block, :klass => klass, :add=>add_block, :publish_after_save => publish_after_save, :saved_template => true)
|
|
2508
|
-
else
|
|
2509
|
-
form = expand_block(form_block, :klass => klass, :add=>add_block, :make_form=>true, :publish_after_save => publish_after_save, :saved_template => true)
|
|
2510
|
-
end
|
|
2511
|
-
out helper.save_erb_to_url(form, form_url)
|
|
2512
|
-
else
|
|
2513
|
-
# no form, render, edit and add are not ajax
|
|
2514
|
-
if descendant('add') || descendant('add_document')
|
|
2515
|
-
out "<% if (#{list_var} = #{list_finder}) || (#{node}.#{node_kind_of?(Comment) ? "can_comment?" : "can_write?"} && #{list_var}=[]) -%>"
|
|
2516
|
-
elsif list_finder != 'nil'
|
|
2517
|
-
out "<% if #{list_var} = #{list_finder} -%>"
|
|
2518
|
-
else
|
|
2519
|
-
out "<% if nil -%>"
|
|
2520
|
-
end
|
|
2521
|
-
|
|
2522
|
-
if query && (pagination_key = query.pagination_key)
|
|
2523
|
-
out "<% set_#{pagination_key}_nodes = #{query.finder(:count)}; set_#{pagination_key}_count = (set_#{pagination_key}_nodes / #{query.page_size.to_f}).ceil; set_#{pagination_key} = [1,params[:#{pagination_key}].to_i].max -%>"
|
|
2524
|
-
@context[:paginate] = pagination_key
|
|
2525
|
-
@context[:vars] ||= []
|
|
2526
|
-
@context[:vars] << "#{pagination_key}_nodes"
|
|
2527
|
-
@context[:vars] << "#{pagination_key}_count"
|
|
2528
|
-
@context[:vars] << "#{pagination_key}"
|
|
2529
|
-
end
|
|
2530
|
-
|
|
2531
|
-
out render_html_tag(expand_with(:list=>list_var, :in_if => false))
|
|
2532
|
-
out expand_with(:in_if=>true, :only=>['elsif', 'else'], :html_tag => @html_tag, :html_tag_params => @html_tag_params)
|
|
2533
|
-
out "<% end -%>"
|
|
2534
|
-
end
|
|
2535
|
-
end
|
|
2536
|
-
|
|
2537
|
-
def _(text)
|
|
2538
|
-
if @context[:dict]
|
|
2539
|
-
@context[:dict][text] || helper.send(:_,text)
|
|
2540
|
-
else
|
|
2541
|
-
helper.send(:_,text)
|
|
2542
|
-
end
|
|
2543
|
-
end
|
|
2544
|
-
|
|
2545
|
-
# Find a block to update on the page
|
|
2546
|
-
def find_target(name)
|
|
2547
|
-
# find dom_id / template_url
|
|
2548
|
-
target = nil
|
|
2549
|
-
root.descendants('block').each do |b|
|
|
2550
|
-
if b.name == name
|
|
2551
|
-
target = b
|
|
2552
|
-
break
|
|
2553
|
-
end
|
|
2554
|
-
end
|
|
2555
|
-
out parser_error("could not find a block named '#{name}'") if target.nil?
|
|
2556
|
-
target
|
|
2557
|
-
end
|
|
2558
|
-
|
|
2559
|
-
# DOM id for the current context
|
|
2560
|
-
def dom_id(suffix='')
|
|
2561
|
-
return "\#{dom_id(#{node})}" if @context && (@context[:saved_template] && @context[:main_node])
|
|
2562
|
-
if @context && scope_node = @context[:scope_node]
|
|
2563
|
-
res = "#{dom_prefix}_\#{#{scope_node}.zip}"
|
|
2564
|
-
else
|
|
2565
|
-
res = dom_prefix
|
|
2566
|
-
end
|
|
2567
|
-
if (method == 'each' || method == 'each_group') && !@context[:make_form]
|
|
2568
|
-
"#{res}_\#{#{var}.zip}"
|
|
2569
|
-
elsif @context && @context[:in_calendar]
|
|
2570
|
-
"#{res}_\#{#{current_date}.to_i}"
|
|
2571
|
-
elsif method == 'unlink' || method == 'edit'
|
|
2572
|
-
target = nil
|
|
2573
|
-
parent = self.parent
|
|
2574
|
-
while parent
|
|
2575
|
-
if ['block', 'each', 'context', 'icon'].include?(parent.method)
|
|
2576
|
-
target = parent
|
|
2577
|
-
break
|
|
2578
|
-
end
|
|
2579
|
-
parent = parent.parent
|
|
2580
|
-
end
|
|
2581
|
-
target ? target.dom_id(suffix) : (res + suffix)
|
|
2582
|
-
else
|
|
2583
|
-
res + suffix
|
|
2584
|
-
end
|
|
2585
|
-
end
|
|
2586
|
-
|
|
2587
|
-
def erb_dom_id(suffix='')
|
|
2588
|
-
return "<%= dom_id(#{node}) %>" if @context && (@context[:saved_template] && @context[:main_node])
|
|
2589
|
-
if @context && scope_node = @context[:scope_node]
|
|
2590
|
-
res = "#{dom_prefix}_<%= #{scope_node}.zip %>"
|
|
2591
|
-
else
|
|
2592
|
-
res = dom_prefix
|
|
2593
|
-
end
|
|
2594
|
-
if (method == 'each' || method == 'each_group') && !@context[:make_form]
|
|
2595
|
-
"#{res}_<%= #{var}.zip %>"
|
|
2596
|
-
elsif method == 'draggable'
|
|
2597
|
-
"#{res}_<%= #{node}.zip %>"
|
|
2598
|
-
elsif @context && @context[:in_calendar]
|
|
2599
|
-
"#{res}_<%= #{current_date}.to_i %>"
|
|
2600
|
-
elsif method == 'unlink'
|
|
2601
|
-
target = nil
|
|
2602
|
-
parent = self.parent
|
|
2603
|
-
while parent
|
|
2604
|
-
if ['block', 'each', 'context', 'icon'].include?(parent.method)
|
|
2605
|
-
target = parent
|
|
2606
|
-
break
|
|
2607
|
-
end
|
|
2608
|
-
parent = parent.parent
|
|
2609
|
-
end
|
|
2610
|
-
target ? target.erb_dom_id(suffix) : (res + suffix)
|
|
2611
|
-
else
|
|
2612
|
-
res + suffix
|
|
2613
|
-
end
|
|
2614
|
-
end
|
|
2615
|
-
|
|
2616
|
-
# Unique template_url, ending with dom_id
|
|
2617
|
-
def template_url
|
|
2618
|
-
"#{@options[:root]}/#{dom_prefix}"
|
|
2619
|
-
end
|
|
2620
|
-
|
|
2621
|
-
def form_url
|
|
2622
|
-
template_url + '_form'
|
|
2623
|
-
end
|
|
2624
|
-
|
|
2625
|
-
# Return parameter value accessor
|
|
2626
|
-
def get_param(key)
|
|
2627
|
-
"params[:#{key}]"
|
|
2628
|
-
end
|
|
2629
|
-
|
|
2630
|
-
def context
|
|
2631
|
-
return @context if @context
|
|
2632
|
-
# not rendered yet, find first parent with context
|
|
2633
|
-
@context = parent ? parent.context : {}
|
|
2634
|
-
end
|
|
2635
|
-
|
|
2636
|
-
# prefix for DOM id
|
|
2637
|
-
def dom_prefix
|
|
2638
|
-
(@context ? @context[:dom_prefix] : nil) || (@dom_prefix ||= unique_name)
|
|
2639
|
-
end
|
|
2640
|
-
|
|
2641
|
-
# use our own scope
|
|
2642
|
-
def clear_dom_scope
|
|
2643
|
-
@context.delete(:make_form) # should not propagate
|
|
2644
|
-
@context.delete(:main_node) # should not propagate
|
|
2645
|
-
end
|
|
2646
|
-
|
|
2647
|
-
# create our own ajax DOM scope
|
|
2648
|
-
def new_dom_scope
|
|
2649
|
-
clear_dom_scope
|
|
2650
|
-
@context.delete(:saved_template) # should not propagate on fresh template
|
|
2651
|
-
@context.delete(:dom_prefix) # should not propagate on fresh template
|
|
2652
|
-
@context[:main_node] = true # the current context will be rendered with a fresh '@node'
|
|
2653
|
-
@context[:dom_prefix] = self.dom_prefix
|
|
2654
|
-
end
|
|
2655
|
-
|
|
2656
|
-
# Return a different name on each call
|
|
2657
|
-
def unique_name(base = context_name)
|
|
2658
|
-
root.next_name_index(base, base == @name).gsub(/[^\d\w\/]/,'_')
|
|
2659
|
-
end
|
|
2660
|
-
|
|
2661
|
-
def context_name
|
|
2662
|
-
@name || if @context
|
|
2663
|
-
@context[:name] || 'list'
|
|
2664
|
-
elsif parent
|
|
2665
|
-
parent.context_name
|
|
2666
|
-
else
|
|
2667
|
-
'root'
|
|
2668
|
-
end
|
|
2669
|
-
end
|
|
2670
|
-
|
|
2671
|
-
def next_name_index(key, own_id = false)
|
|
2672
|
-
@next_name_index ||= {}
|
|
2673
|
-
if @next_name_index[key]
|
|
2674
|
-
@next_name_index[key] += 1
|
|
2675
|
-
key + @next_name_index[key].to_s
|
|
2676
|
-
elsif own_id
|
|
2677
|
-
@next_name_index[key] = 0
|
|
2678
|
-
key
|
|
2679
|
-
else
|
|
2680
|
-
@next_name_index[key] = 1
|
|
2681
|
-
key + '1'
|
|
2682
|
-
end
|
|
2683
|
-
end
|
|
2684
|
-
|
|
2685
|
-
def add_params(text, opts={}, inner = '')
|
|
2686
|
-
text.sub(/\A([^<]*)<(\w+)(( .*?)[^%]|)>/) do
|
|
2687
|
-
# we must set the first tag id
|
|
2688
|
-
before = $1
|
|
2689
|
-
tag = $2
|
|
2690
|
-
params = parse_params($3)
|
|
2691
|
-
opts.each do |k,v|
|
|
2692
|
-
next unless v
|
|
2693
|
-
params[k] = v
|
|
2694
|
-
end
|
|
2695
|
-
"#{before}<#{tag}#{params_to_html(params)}>#{inner}"
|
|
2696
|
-
end
|
|
2697
|
-
end
|
|
2698
|
-
|
|
2699
|
-
# TODO: RUBYLESS
|
|
2700
|
-
def get_test_condition(node = self.node, params = @params)
|
|
2701
|
-
tests = []
|
|
2702
|
-
params.each do |k,v|
|
|
2703
|
-
if k.to_s =~ /^(or_|)([a-zA-Z_]+)(\d*)$/
|
|
2704
|
-
k = $2.to_sym
|
|
2705
|
-
end #tagged undocumented
|
|
2706
|
-
if [:kind_of, :klass, :status, :lang, :can, :tagged, :node, :in, :visitor, :has].include?(k)
|
|
2707
|
-
tests << [k, v]
|
|
2708
|
-
elsif k == :test
|
|
2709
|
-
if v =~ /\s/
|
|
2710
|
-
tests << [:test, v]
|
|
2711
|
-
else
|
|
2712
|
-
tests << [:attribute, v]
|
|
2713
|
-
end
|
|
2714
|
-
end
|
|
2715
|
-
end
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
tests.map! do |type,value|
|
|
2719
|
-
case type
|
|
2720
|
-
when :kind_of
|
|
2721
|
-
"#{node}.vkind_of?(#{value.inspect})"
|
|
2722
|
-
when :klass
|
|
2723
|
-
klass = begin Module::const_get(value) rescue "NilClass" end
|
|
2724
|
-
"#{node}.klass == #{value.inspect}"
|
|
2725
|
-
when :status
|
|
2726
|
-
"#{node}.version.status == #{Zena::Status[value.to_sym]}"
|
|
2727
|
-
when :tagged
|
|
2728
|
-
# TODO: undocumented: remove and use rubyless !
|
|
2729
|
-
"#{node}.tagged[#{value.inspect}]"
|
|
2730
|
-
when :lang
|
|
2731
|
-
"#{node}.version.lang == #{value.inspect}"
|
|
2732
|
-
when :can
|
|
2733
|
-
# TODO: test
|
|
2734
|
-
case value
|
|
2735
|
-
when 'write', 'edit'
|
|
2736
|
-
"#{node}.can_write?"
|
|
2737
|
-
when 'drive', 'publish'
|
|
2738
|
-
"#{node}.can_drive?"
|
|
2739
|
-
else
|
|
2740
|
-
nil
|
|
2741
|
-
end
|
|
2742
|
-
when :has
|
|
2743
|
-
case value
|
|
2744
|
-
when 'discussion'
|
|
2745
|
-
"#{node}.discussion"
|
|
2746
|
-
else
|
|
2747
|
-
nil
|
|
2748
|
-
end
|
|
2749
|
-
when :test
|
|
2750
|
-
parse_condition(value, node)
|
|
2751
|
-
when :attribute
|
|
2752
|
-
'!' + node_attribute(value, :node => node) + '.blank?'
|
|
2753
|
-
when :node
|
|
2754
|
-
if node_kind_of?(Node)
|
|
2755
|
-
value, node_name = get_attribute_and_node(value)
|
|
2756
|
-
node_name ||= '@node'
|
|
2757
|
-
if value
|
|
2758
|
-
case value
|
|
2759
|
-
when 'main'
|
|
2760
|
-
"#{node}[:id] == #{node_name}[:id]"
|
|
2761
|
-
when 'start'
|
|
2762
|
-
"#{node}[:zip] == (params[:s] || @node[:zip]).to_i"
|
|
2763
|
-
when 'parent'
|
|
2764
|
-
"#{node}[:id] == #{node_name}[:parent_id]"
|
|
2765
|
-
when 'project'
|
|
2766
|
-
"#{node}[:id] == #{node_name}[:project_id]"
|
|
2767
|
-
when 'section'
|
|
2768
|
-
"#{node}[:id] == #{node_name}[:section_id]"
|
|
2769
|
-
when 'ancestor'
|
|
2770
|
-
"#{node_name}.fullpath =~ /\\A\#{#{node}.fullpath}/"
|
|
2771
|
-
else
|
|
2772
|
-
if stored = find_stored(Node, value)
|
|
2773
|
-
"#{node}[:id] == #{stored}[:id]"
|
|
2774
|
-
else
|
|
2775
|
-
nil
|
|
2776
|
-
end
|
|
2777
|
-
end
|
|
2778
|
-
else
|
|
2779
|
-
# bad node_name
|
|
2780
|
-
nil
|
|
2781
|
-
end
|
|
2782
|
-
else
|
|
2783
|
-
nil
|
|
2784
|
-
end
|
|
2785
|
-
when :in
|
|
2786
|
-
if @context["in_#{value}".to_sym] # FIXME: || ancestors.include?(value) ==> ancestors is a list of zafu tags, not a list of names !
|
|
2787
|
-
'true'
|
|
2788
|
-
else
|
|
2789
|
-
'false'
|
|
2790
|
-
end
|
|
2791
|
-
when :visitor
|
|
2792
|
-
if value == 'anon'
|
|
2793
|
-
"visitor.is_anon?"
|
|
2794
|
-
else
|
|
2795
|
-
nil
|
|
2796
|
-
end
|
|
2797
|
-
else
|
|
2798
|
-
nil
|
|
2799
|
-
end
|
|
2800
|
-
end.compact!
|
|
2801
|
-
tests == [] ? nil : tests.join(' || ')
|
|
2802
|
-
end
|
|
2803
|
-
|
|
2804
|
-
def parse_condition_error(clause, rest, res)
|
|
2805
|
-
out parser_error("invalid clause #{clause.inspect} near \"#{res[-2..-1]}#{rest[0..1]}\"")
|
|
2806
|
-
end
|
|
2807
|
-
|
|
2808
|
-
def parse_condition(clause, node_name)
|
|
2809
|
-
rest = clause.strip
|
|
2810
|
-
types = [:par_open, :value, :bool_op, :op, :par_close]
|
|
2811
|
-
allowed = [:par_open, :value]
|
|
2812
|
-
par_count = 0
|
|
2813
|
-
uses_bool_op = false
|
|
2814
|
-
segment = [] # value op value
|
|
2815
|
-
after_value = lambda { segment.size == 3 ? [:bool_op, :par_close] : [:op, :bool_op, :par_close]}
|
|
2816
|
-
res = ""
|
|
2817
|
-
while rest != ''
|
|
2818
|
-
# puts rest.inspect
|
|
2819
|
-
if rest =~ /\A\s+/
|
|
2820
|
-
rest = rest[$&.size..-1]
|
|
2821
|
-
elsif rest[0..0] == '('
|
|
2822
|
-
unless allowed.include?(:par_open)
|
|
2823
|
-
parse_condition_error(clause, rest, res)
|
|
2824
|
-
return nil
|
|
2825
|
-
end
|
|
2826
|
-
res << '('
|
|
2827
|
-
rest = rest[1..-1]
|
|
2828
|
-
par_count += 1
|
|
2829
|
-
elsif rest[0..0] == ')'
|
|
2830
|
-
unless allowed.include?(:par_close)
|
|
2831
|
-
parse_condition_error(clause, rest, res)
|
|
2832
|
-
return nil
|
|
2833
|
-
end
|
|
2834
|
-
res << ')'
|
|
2835
|
-
rest = rest[1..-1]
|
|
2836
|
-
par_count -= 1
|
|
2837
|
-
if par_count < 0
|
|
2838
|
-
parse_condition_error(clause, rest, res)
|
|
2839
|
-
return nil
|
|
2840
|
-
end
|
|
2841
|
-
allowed = [:bool_op]
|
|
2842
|
-
elsif rest =~ /\A(lt|le|eq|ne|ge|gt)\s+/
|
|
2843
|
-
unless allowed.include?(:op)
|
|
2844
|
-
parse_condition_error(clause, rest, res)
|
|
2845
|
-
return nil
|
|
2846
|
-
end
|
|
2847
|
-
op = $1.strip
|
|
2848
|
-
rest = rest[op.size..-1]
|
|
2849
|
-
op = {'lt' => '<', 'le' => '<=', 'eq' => '==', 'ne' => '!=', 'ge' => '>=', 'gt' => '>'}[op]
|
|
2850
|
-
segment << [op, :op]
|
|
2851
|
-
allowed = [:value]
|
|
2852
|
-
elsif rest =~ /\A("|')([^\1]*?)\1/
|
|
2853
|
-
# string
|
|
2854
|
-
unless allowed.include?(:value)
|
|
2855
|
-
parse_condition_error(clause, rest, res)
|
|
2856
|
-
return nil
|
|
2857
|
-
end
|
|
2858
|
-
rest = rest[$&.size..-1]
|
|
2859
|
-
segment << [$2.inspect, :string]
|
|
2860
|
-
allowed = after_value.call
|
|
2861
|
-
elsif rest =~ /\A(-?\d+)/
|
|
2862
|
-
# number
|
|
2863
|
-
unless allowed.include?(:value)
|
|
2864
|
-
parse_condition_error(clause, rest, res)
|
|
2865
|
-
return nil
|
|
2866
|
-
end
|
|
2867
|
-
rest = rest[$&.size..-1]
|
|
2868
|
-
segment << [$1, :number]
|
|
2869
|
-
allowed = after_value.call
|
|
2870
|
-
elsif rest =~ /\A(and|or)/
|
|
2871
|
-
unless allowed.include?(:bool_op)
|
|
2872
|
-
parse_condition_error(clause, rest, res)
|
|
2873
|
-
return nil
|
|
2874
|
-
end
|
|
2875
|
-
uses_bool_op = true
|
|
2876
|
-
rest = rest[$&.size..-1]
|
|
2877
|
-
res << " #{$1} "
|
|
2878
|
-
allowed = [:par_open, :value]
|
|
2879
|
-
elsif rest =~ /\A([\w:\.\-]+)/
|
|
2880
|
-
# variable
|
|
2881
|
-
unless allowed.include?(:value)
|
|
2882
|
-
parse_condition_error(clause, rest, res)
|
|
2883
|
-
return nil
|
|
2884
|
-
end
|
|
2885
|
-
rest = rest[$&.size..-1]
|
|
2886
|
-
fld = $1
|
|
2887
|
-
unless node_attr = node_attribute(fld, :node => node_name)
|
|
2888
|
-
parser_error("invalid field #{fld.inspect}")
|
|
2889
|
-
return nil
|
|
2890
|
-
end
|
|
2891
|
-
segment << [node_attr, :var]
|
|
2892
|
-
allowed = after_value.call
|
|
2893
|
-
else
|
|
2894
|
-
parse_condition_error(clause, rest, res)
|
|
2895
|
-
return nil
|
|
2896
|
-
end
|
|
2897
|
-
if segment.size == 3
|
|
2898
|
-
toi = (segment[1][0] =~ /(>|<)/ || (segment[0][1] == :number || segment[2][1] == :number))
|
|
2899
|
-
segment.map! do |part, type|
|
|
2900
|
-
if type == :var
|
|
2901
|
-
toi ? "#{part}.to_i" : part
|
|
2902
|
-
elsif type == :string
|
|
2903
|
-
toi ? part[1..-2].to_i : part
|
|
2904
|
-
else
|
|
2905
|
-
part
|
|
2906
|
-
end
|
|
2907
|
-
end
|
|
2908
|
-
res << segment.join(" ")
|
|
2909
|
-
segment = []
|
|
2910
|
-
end
|
|
2911
|
-
end
|
|
2912
|
-
|
|
2913
|
-
if par_count > 0
|
|
2914
|
-
parser_error("invalid clause #{clause.inspect}: missing closing ')'")
|
|
2915
|
-
return nil
|
|
2916
|
-
elsif allowed.include?(:value)
|
|
2917
|
-
parser_error("invalid clause #{clause.inspect}")
|
|
2918
|
-
return nil
|
|
2919
|
-
else
|
|
2920
|
-
return uses_bool_op ? "(#{res})" : res
|
|
2921
|
-
end
|
|
2922
|
-
end
|
|
2923
|
-
|
|
2924
|
-
# Block visibility of descendance with 'do_list'.
|
|
2925
|
-
def public_descendants
|
|
2926
|
-
all = super
|
|
2927
|
-
if ['context', 'each', 'block'].include?(self.method)
|
|
2928
|
-
# do not propagate 'form',etc up
|
|
2929
|
-
all.reject do |k,v|
|
|
2930
|
-
['form','unlink'].include?(k)
|
|
2931
|
-
end
|
|
2932
|
-
elsif ['if', 'case'].include?(self.method)
|
|
2933
|
-
all.reject do |k,v|
|
|
2934
|
-
['else', 'elsif', 'when'].include?(k)
|
|
2935
|
-
end
|
|
2936
|
-
else
|
|
2937
|
-
all
|
|
2938
|
-
end
|
|
2939
|
-
end
|
|
2940
|
-
|
|
2941
|
-
def single_child_method
|
|
2942
|
-
return @single_child_method if defined?(@single_child_method)
|
|
2943
|
-
@single_child_method = if @blocks.size == 1
|
|
2944
|
-
single_child = @blocks[0]
|
|
2945
|
-
return nil if single_child.kind_of?(String)
|
|
2946
|
-
single_child.html_tag ? nil : single_child.method
|
|
2947
|
-
else
|
|
2948
|
-
nil
|
|
2949
|
-
end
|
|
2950
|
-
end
|
|
2951
|
-
|
|
2952
|
-
def get_attribute_and_node(str)
|
|
2953
|
-
if str =~ /([^\.]+)\.(.+)/
|
|
2954
|
-
node_name = $1
|
|
2955
|
-
node_attr = $2
|
|
2956
|
-
if att_node = find_stored(Node, node_name)
|
|
2957
|
-
return [node_attr, att_node, Node]
|
|
2958
|
-
elsif node_name == 'main'
|
|
2959
|
-
return [node_attr, '@node', Node]
|
|
2960
|
-
elsif node_name == 'visitor'
|
|
2961
|
-
return [node_attr, 'visitor.contact', Contact]
|
|
2962
|
-
elsif node_name == 'site'
|
|
2963
|
-
return [node_attr, 'current_site', Site]
|
|
2964
|
-
else
|
|
2965
|
-
out parser_error("invalid node name #{node_name.inspect} in attribute #{str.inspect}")
|
|
2966
|
-
return [nil]
|
|
2967
|
-
end
|
|
2968
|
-
else
|
|
2969
|
-
return [str]
|
|
2970
|
-
end
|
|
2971
|
-
end
|
|
2972
|
-
|
|
2973
|
-
def parse_attributes_in_value(v, opts = {})
|
|
2974
|
-
opts = {:erb => true}.merge(opts)
|
|
2975
|
-
static = true
|
|
2976
|
-
|
|
2977
|
-
use_node = @var || node
|
|
2978
|
-
res = v.gsub(/\[([^\]]+)\]/) do
|
|
2979
|
-
static = false
|
|
2980
|
-
res = nil
|
|
2981
|
-
attribute = $1
|
|
2982
|
-
|
|
2983
|
-
if opts[:skip_node_attributes]
|
|
2984
|
-
if attribute =~ /^param:(\w+)$/
|
|
2985
|
-
attribute = get_param($1)
|
|
2986
|
-
elsif attribute == 'current_date'
|
|
2987
|
-
attribute = current_date
|
|
2988
|
-
else
|
|
2989
|
-
res = "[#{attribute}]"
|
|
2990
|
-
end
|
|
2991
|
-
else
|
|
2992
|
-
attribute = node_attribute(attribute, :node => use_node )
|
|
2993
|
-
end
|
|
2994
|
-
|
|
2995
|
-
res ||= if opts[:erb]
|
|
2996
|
-
"<%= #{attribute} %>"
|
|
2997
|
-
else
|
|
2998
|
-
"\#{#{attribute}}"
|
|
2999
|
-
end
|
|
3000
|
-
res
|
|
3001
|
-
end
|
|
3002
|
-
[res, static]
|
|
3003
|
-
end
|
|
3004
|
-
|
|
3005
|
-
def node_attribute(str, opts={})
|
|
3006
|
-
|
|
3007
|
-
if @context[:vars] && @context[:vars].include?(str)
|
|
3008
|
-
return "set_#{str}"
|
|
3009
|
-
end
|
|
3010
|
-
|
|
3011
|
-
res = PSEUDO_ATTRIBUTES[str]
|
|
3012
|
-
return res if res
|
|
3013
|
-
return current_date if str == 'current_date'
|
|
3014
|
-
return get_param($1) if str =~ /^param:(\w+)$/
|
|
3015
|
-
|
|
3016
|
-
attribute, att_node, klass = get_attribute_and_node(str)
|
|
3017
|
-
|
|
3018
|
-
return 'nil' unless attribute
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
att_node ||= opts[:node] || node
|
|
3022
|
-
klass ||= opts[:node_class] || node_class
|
|
3023
|
-
|
|
3024
|
-
real_attribute = attribute =~ /\Ad_/ ? attribute : attribute.gsub(/\A(|[\w_]+)id(s?)\Z/, '\1zip\2')
|
|
3025
|
-
|
|
3026
|
-
res = if klass.ancestors.include?(Node)
|
|
3027
|
-
if ['url','path'].include?(real_attribute)
|
|
3028
|
-
# pseudo attribute 'url'
|
|
3029
|
-
params = {}
|
|
3030
|
-
params[:mode] = @params[:mode] if @params[:mode]
|
|
3031
|
-
params[:format] = @params[:format] if @params[:format]
|
|
3032
|
-
"zen_#{real_attribute}(#{node}#{params_to_erb(params)})"
|
|
3033
|
-
elsif type = safe_method_type([real_attribute])
|
|
3034
|
-
type[:method]
|
|
3035
|
-
elsif type = klass.safe_method_type([real_attribute])
|
|
3036
|
-
"#{att_node}.#{type[:method]}"
|
|
3037
|
-
else
|
|
3038
|
-
"#{att_node}.safe_read(#{real_attribute.inspect})"
|
|
3039
|
-
end
|
|
3040
|
-
elsif type = klass.safe_method_type([real_attribute])
|
|
3041
|
-
"#{att_node}.#{type[:method]}"
|
|
3042
|
-
else
|
|
3043
|
-
# unknown class, resolve at runtime
|
|
3044
|
-
"#{att_node}.safe_read(#{real_attribute.inspect})"
|
|
3045
|
-
end
|
|
3046
|
-
|
|
3047
|
-
res = "(#{res} || #{node_attribute(opts[:else])})" if opts[:else]
|
|
3048
|
-
res = "(#{res} || #{opts[:default].inspect})" if opts[:default]
|
|
3049
|
-
res
|
|
3050
|
-
end
|
|
3051
|
-
|
|
3052
|
-
# Add a class name to the html_tag
|
|
3053
|
-
def add_html_class(class_name)
|
|
3054
|
-
if klass = @html_tag_params[:class]
|
|
3055
|
-
@html_tag_params[:class] = "#{class_name} #{klass}"
|
|
3056
|
-
else
|
|
3057
|
-
@html_tag_params[:class] = class_name
|
|
3058
|
-
end
|
|
3059
|
-
end
|
|
3060
|
-
|
|
3061
|
-
def render_html_tag(text,*append)
|
|
3062
|
-
append ||= []
|
|
3063
|
-
return text if @html_tag_done
|
|
3064
|
-
set_params = {}
|
|
3065
|
-
if_params = {}
|
|
3066
|
-
@params.each do |k,v|
|
|
3067
|
-
if k.to_s =~ /^t?set_/
|
|
3068
|
-
set_params[k] = v
|
|
3069
|
-
end
|
|
3070
|
-
end
|
|
3071
|
-
tag_class = @html_tag_params[:class] || @params[:class]
|
|
3072
|
-
if node_kind_of?(Node)
|
|
3073
|
-
|
|
3074
|
-
if @context[:make_form]
|
|
3075
|
-
node_name = node
|
|
3076
|
-
elsif (@method == 'each' || @method == 'each_group') && @context[:list]
|
|
3077
|
-
node_name = var
|
|
3078
|
-
elsif @method == 'context'
|
|
3079
|
-
node_name = @var || node
|
|
3080
|
-
else
|
|
3081
|
-
node_name = node
|
|
3082
|
-
end
|
|
3083
|
-
|
|
3084
|
-
class_cond = nil
|
|
3085
|
-
@params.each do |k,v|
|
|
3086
|
-
if k.to_s =~ /^(.+)_if$/
|
|
3087
|
-
klass = $1
|
|
3088
|
-
cond = get_test_condition(node_name, :test => v)
|
|
3089
|
-
elsif k.to_s =~ /^(.+)_if_(test|node|kind_of|klass|status|lang|can|in)$/
|
|
3090
|
-
klass = $1
|
|
3091
|
-
cond = get_test_condition(node_name, $2.to_sym => v)
|
|
3092
|
-
end
|
|
3093
|
-
if cond
|
|
3094
|
-
class_cond = "#{cond} ? \" class='#{klass}'\" : #{class_cond}" # (x = 3) ? "class='foo'" :
|
|
3095
|
-
end
|
|
3096
|
-
end
|
|
3097
|
-
|
|
3098
|
-
if class_cond
|
|
3099
|
-
append << "<%= #{class_cond}\"#{tag_class ? " class='#{tag_class}'" : ""}\" %>"
|
|
3100
|
-
@html_tag_params.delete(:class)
|
|
3101
|
-
end
|
|
3102
|
-
end
|
|
3103
|
-
|
|
3104
|
-
@html_tag = 'div' if !@html_tag && (set_params != {} || @html_tag_params != {})
|
|
3105
|
-
|
|
3106
|
-
bak = @html_tag_params.dup
|
|
3107
|
-
@html_tag_params = get_html_params(set_params.merge(@html_tag_params), @html_tag)
|
|
3108
|
-
res = super(text,*append)
|
|
3109
|
-
@html_tag_params = bak
|
|
3110
|
-
res
|
|
3111
|
-
end
|
|
3112
|
-
|
|
3113
|
-
def link_to_update(target, opts = {})
|
|
3114
|
-
method = opts[:method] || :get
|
|
3115
|
-
|
|
3116
|
-
html_params = opts[:html_params] || {}
|
|
3117
|
-
node_id = opts[:node_id] || self.node_id
|
|
3118
|
-
|
|
3119
|
-
url = opts[:url] || "/#{base_class.to_s.pluralize.underscore}/\#{#{node_id}}#{method == :get ? '/zafu' : ''}"
|
|
3120
|
-
opts[:cond] ||= "#{node}.can_write?" if method != :get
|
|
3121
|
-
|
|
3122
|
-
query_params = [opts[:query_params]].flatten.compact
|
|
3123
|
-
|
|
3124
|
-
if method == :get
|
|
3125
|
-
if target
|
|
3126
|
-
query_params << "t_url=#{CGI.escape(target.template_url)}"
|
|
3127
|
-
query_params << "dom_id=#{target.dom_id}"
|
|
3128
|
-
else
|
|
3129
|
-
query_params << "dom_id=_page"
|
|
3130
|
-
end
|
|
3131
|
-
else
|
|
3132
|
-
query_params << "t_url=#{CGI.escape(template_url)}" if method != :delete
|
|
3133
|
-
|
|
3134
|
-
query_params << "dom_id=#{dom_id}"
|
|
3135
|
-
if target != self
|
|
3136
|
-
if target
|
|
3137
|
-
query_params << "u_url=#{CGI.escape(target.template_url)}"
|
|
3138
|
-
query_params << "udom_id=#{target.dom_id}"
|
|
3139
|
-
else
|
|
3140
|
-
query_params << "udom_id=_page"
|
|
3141
|
-
end
|
|
3142
|
-
end
|
|
3143
|
-
end
|
|
3144
|
-
|
|
3145
|
-
query_params << "link_id=\#{#{node}.link_id}" if @context[:need_link_id] && node_kind_of?(Node)
|
|
3146
|
-
query_params << "node[v_status]=#{Zena::Status[:pub]}" if @params[:publish] # FIXME: this acts like publish = 'force'
|
|
3147
|
-
query_params << start_node_s_param(:string)
|
|
3148
|
-
|
|
3149
|
-
res = ''
|
|
3150
|
-
res += "<% if #{opts[:cond]} -%>" if opts[:cond]
|
|
3151
|
-
res += "<%= tag_to_remote({:url => \"#{url}?#{query_params.join('&')}\", :method => #{method.inspect}}#{params_to_erb(html_params)}) %>"
|
|
3152
|
-
res += text_for_link(opts[:default_text])
|
|
3153
|
-
res += "</a>"
|
|
3154
|
-
if opts[:cond]
|
|
3155
|
-
if opts[:else] != :void
|
|
3156
|
-
res += "<% else -%>"
|
|
3157
|
-
res += text_for_link(opts[:default_text])
|
|
3158
|
-
end
|
|
3159
|
-
res += "<% end -%>"
|
|
3160
|
-
end
|
|
3161
|
-
res
|
|
3162
|
-
end
|
|
3163
|
-
|
|
3164
|
-
def text_for_link(default = nil)
|
|
3165
|
-
if @blocks.size > 1 || (@blocks.size == 1 && !(@blocks.first.kind_of?(String) || ['else','elsif'].include?(@blocks.first.method)))
|
|
3166
|
-
expand_with
|
|
3167
|
-
elsif default
|
|
3168
|
-
default
|
|
3169
|
-
elsif erb_text = get_text_for_erb(@params, false, :string)
|
|
3170
|
-
erb_text
|
|
3171
|
-
elsif node_kind_of?(Node)
|
|
3172
|
-
"<%= #{node}.version.title %>"
|
|
3173
|
-
elsif node_kind_of?(Version)
|
|
3174
|
-
"<%= #{node}.title %>"
|
|
3175
|
-
elsif node_kind_of?(Link)
|
|
3176
|
-
"<%= #{node}.name %>"
|
|
3177
|
-
else
|
|
3178
|
-
_('edit')
|
|
3179
|
-
end
|
|
3180
|
-
end
|
|
3181
|
-
|
|
3182
|
-
def get_text_for_erb(params = @params, use_blocks = true, context = :erb)
|
|
3183
|
-
string_context = context == :string
|
|
3184
|
-
if params[:attr]
|
|
3185
|
-
string_context ? "<%= #{node_attribute(params[:attr])} %>" : node_attribute(params[:attr])
|
|
3186
|
-
elsif params[:tattr]
|
|
3187
|
-
string_context ? "<%= _(#{node_attribute(params[:tattr])}) %>" : "_(#{node_attribute(params[:tattr])})"
|
|
3188
|
-
elsif params[:trans]
|
|
3189
|
-
string_context ? _(params[:trans]) : _(params[:trans]).inspect
|
|
3190
|
-
elsif params[:text]
|
|
3191
|
-
string_context ? params[:text] : params[:text].inspect
|
|
3192
|
-
elsif use_blocks && @blocks != []
|
|
3193
|
-
res = []
|
|
3194
|
-
text = ""
|
|
3195
|
-
static = true
|
|
3196
|
-
@blocks.each do |b|
|
|
3197
|
-
# FIXME: this is a little too hacky
|
|
3198
|
-
if b.kind_of?(String)
|
|
3199
|
-
res << b.inspect
|
|
3200
|
-
text << b
|
|
3201
|
-
elsif ['show', 'img'].include?(b.method)
|
|
3202
|
-
res << expand_block(b, :trans=>true)
|
|
3203
|
-
static = false
|
|
3204
|
-
elsif ['rename_asset', 'trans'].include?(b.method)
|
|
3205
|
-
# FIXME: if a trans contains non-static: static should become false
|
|
3206
|
-
res << expand_block(b).inspect
|
|
3207
|
-
text << expand_block(b)
|
|
3208
|
-
else
|
|
3209
|
-
# ignore
|
|
3210
|
-
end
|
|
3211
|
-
end
|
|
3212
|
-
if static
|
|
3213
|
-
# "just plain text"
|
|
3214
|
-
string_context ? text : text.inspect
|
|
3215
|
-
else
|
|
3216
|
-
# function(...) + "blah" + function()
|
|
3217
|
-
string_context ? "<%= #{res.join(' + ')} %>" : res.join(' + ')
|
|
3218
|
-
end
|
|
3219
|
-
else
|
|
3220
|
-
nil
|
|
3221
|
-
end
|
|
3222
|
-
end
|
|
3223
|
-
|
|
3224
|
-
def get_input_params(params = @params)
|
|
3225
|
-
res = {}
|
|
3226
|
-
if res[:name] = (params[:name] || params[:date])
|
|
3227
|
-
if res[:name] =~ /\A([\w_]+)\[(.*?)\]/
|
|
3228
|
-
attribute, sub_attr = $1, $2
|
|
3229
|
-
else
|
|
3230
|
-
attribute = res[:name]
|
|
3231
|
-
end
|
|
3232
|
-
|
|
3233
|
-
unless @context[:in_filter] || attribute == 's'
|
|
3234
|
-
if sub_attr
|
|
3235
|
-
res[:name] = "#{base_class.to_s.underscore}[#{attribute}][#{sub_attr}]"
|
|
3236
|
-
else
|
|
3237
|
-
res[:name] = "#{base_class.to_s.underscore}[#{attribute}]"
|
|
3238
|
-
end
|
|
3239
|
-
end
|
|
3240
|
-
|
|
3241
|
-
if sub_attr
|
|
3242
|
-
if (nattr = node_attribute(attribute)) != 'nil'
|
|
3243
|
-
nattr = "#{nattr}[#{sub_attr.inspect}]"
|
|
3244
|
-
end
|
|
3245
|
-
else
|
|
3246
|
-
nattr = node_attribute(attribute)
|
|
3247
|
-
end
|
|
3248
|
-
|
|
3249
|
-
if sub_attr && params[:type] == 'checkbox' && !params[:value]
|
|
3250
|
-
# Special case when we have a sub_attribute: default value for "tagged[foobar]" is "foobar"
|
|
3251
|
-
params[:value] = sub_attr
|
|
3252
|
-
end
|
|
3253
|
-
|
|
3254
|
-
if @context[:in_add]
|
|
3255
|
-
res[:value] = (params[:value] || params[:set_value]) ? ["'#{ helper.fquote(params[:value])}'"] : ["''"]
|
|
3256
|
-
elsif @context[:in_filter]
|
|
3257
|
-
res[:value] = attribute ? ["'<%= fquote params[#{attribute.to_sym.inspect}] %>'"] : ["''"]
|
|
3258
|
-
elsif params[:value]
|
|
3259
|
-
res[:value] = ["'#{ helper.fquote(params[:value])}'"]
|
|
3260
|
-
else
|
|
3261
|
-
if nattr != 'nil'
|
|
3262
|
-
res[:value] = ["'<%= fquote #{nattr} %>'"]
|
|
3263
|
-
else
|
|
3264
|
-
res[:value] = ["''"]
|
|
3265
|
-
end
|
|
3266
|
-
end
|
|
3267
|
-
end
|
|
3268
|
-
|
|
3269
|
-
if @context[:dom_prefix]
|
|
3270
|
-
res[:id] = "#{erb_dom_id}_#{attribute}"
|
|
3271
|
-
else
|
|
3272
|
-
res[:id] = params[:id] if params[:id]
|
|
3273
|
-
end
|
|
3274
|
-
|
|
3275
|
-
if params[:type] == 'checkbox' && nattr
|
|
3276
|
-
if value = params[:value]
|
|
3277
|
-
res[:checked] = "<%= #{nattr} == #{value.inspect} ? \" checked='checked'\" : '' %>"
|
|
3278
|
-
else
|
|
3279
|
-
res[:checked] = "<%= #{nattr}.blank? ? '' : \" checked='checked'\" %>"
|
|
3280
|
-
end
|
|
3281
|
-
end
|
|
3282
|
-
|
|
3283
|
-
[:size, :style, :class].each do |k|
|
|
3284
|
-
res[k] = params[k] if params[k]
|
|
3285
|
-
end
|
|
3286
|
-
|
|
3287
|
-
return [res, attribute]
|
|
3288
|
-
end
|
|
3289
|
-
|
|
3290
|
-
def get_html_params(params, tag_type)
|
|
3291
|
-
res = {}
|
|
3292
|
-
params.each do |k,v|
|
|
3293
|
-
next unless v
|
|
3294
|
-
if k.to_s =~ /\A(t?)set_(.+)$/
|
|
3295
|
-
key = $2
|
|
3296
|
-
trans = $1 == 't'
|
|
3297
|
-
value, static = parse_attributes_in_value(v, :erb => !trans)
|
|
3298
|
-
|
|
3299
|
-
if trans
|
|
3300
|
-
if static
|
|
3301
|
-
value = ["'#{_(value)}'"] # array so it is not escaped on render
|
|
3302
|
-
else
|
|
3303
|
-
value = ["'<%= _(\"#{value}\") %>'"] # FIXME: use dict ! array so it is not escaped on render
|
|
3304
|
-
end
|
|
3305
|
-
end
|
|
3306
|
-
res[key.to_sym] = value
|
|
3307
|
-
elsif tag_type == :link && ![:style, :class, :id, :title].include?(k)
|
|
3308
|
-
# bad html parameter for links (some keys for link tags are used as query parameters)
|
|
3309
|
-
# filter out
|
|
3310
|
-
else
|
|
3311
|
-
res[k] ||= v
|
|
3312
|
-
end
|
|
3313
|
-
end
|
|
3314
|
-
|
|
3315
|
-
if params[:anchor]
|
|
3316
|
-
@anchor_param = nil
|
|
3317
|
-
res[:name] = anchor_name(params[:anchor], node)
|
|
3318
|
-
end
|
|
3319
|
-
|
|
3320
|
-
res
|
|
3321
|
-
end
|
|
3322
|
-
|
|
3323
|
-
def get_options_for_select
|
|
3324
|
-
if nodes = @params[:nodes]
|
|
3325
|
-
# TODO: dry with r_checkbox
|
|
3326
|
-
if nodes =~ /^\d+\s*($|,)/
|
|
3327
|
-
# ids
|
|
3328
|
-
# TODO: optimization generate the full query instead of using secure.
|
|
3329
|
-
nodes = nodes.split(',').map{|v| v.to_i}
|
|
3330
|
-
nodes = "(secure(Node) { Node.find(:all, :conditions => 'zip IN (#{nodes.join(',')})') })"
|
|
3331
|
-
else
|
|
3332
|
-
# relation
|
|
3333
|
-
nodes, klass = build_finder_for(:all, nodes)
|
|
3334
|
-
return unless nodes
|
|
3335
|
-
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
|
3336
|
-
end
|
|
3337
|
-
set_attr = @params[:attr] || 'id'
|
|
3338
|
-
show_attr = @params[:show] || 'name'
|
|
3339
|
-
options_list = "[['','']] + (#{nodes} || []).map{|r| [#{node_attribute(show_attr, :node => 'r', :node_class => Node)}, #{node_attribute(set_attr, :node => 'r', :node_class => Node)}.to_s]}"
|
|
3340
|
-
elsif values = @params[:values]
|
|
3341
|
-
options_list = values.split(',').map(&:strip)
|
|
3342
|
-
|
|
3343
|
-
if show = @params[:show]
|
|
3344
|
-
show_values = show.split(',').map(&:strip)
|
|
3345
|
-
elsif show = @params[:tshow]
|
|
3346
|
-
show_values = show.split(',').map do |s|
|
|
3347
|
-
_(s.strip)
|
|
3348
|
-
end
|
|
3349
|
-
end
|
|
3350
|
-
|
|
3351
|
-
if show_values
|
|
3352
|
-
options_list.each_index do |i|
|
|
3353
|
-
options_list[i] = [show_values[i], options_list[i]]
|
|
3354
|
-
end
|
|
3355
|
-
end
|
|
3356
|
-
options_list.inspect
|
|
3357
|
-
end
|
|
3358
|
-
end
|
|
3359
|
-
|
|
3360
|
-
def parse_eval_parameter(str)
|
|
3361
|
-
# evaluate an expression. Can only contain vars, '(', ')', '*', '+', '/', '-', '[attr]'
|
|
3362
|
-
# FIXME: SECURITY (audit this)
|
|
3363
|
-
vars = @context[:vars] || []
|
|
3364
|
-
parts = str.split(/\s+/)
|
|
3365
|
-
res = []
|
|
3366
|
-
test = []
|
|
3367
|
-
parts.each do |p|
|
|
3368
|
-
if p =~ /\[([\w_]+)\]/
|
|
3369
|
-
test << 1
|
|
3370
|
-
res << (node_attribute($1) + '.to_f')
|
|
3371
|
-
elsif p =~ /^[a-zA-Z_]+$/
|
|
3372
|
-
unless vars.include?(p)
|
|
3373
|
-
out parser_error("var #{p.inspect} not set in eval")
|
|
3374
|
-
return nil
|
|
3375
|
-
end
|
|
3376
|
-
test << 1
|
|
3377
|
-
res << "set_#{p}.to_f"
|
|
3378
|
-
elsif ['(', ')', '*', '+', '/', '-'].include?(p)
|
|
3379
|
-
res << p
|
|
3380
|
-
test << p
|
|
3381
|
-
elsif p =~ /^[0-9\.]+$/
|
|
3382
|
-
res << p
|
|
3383
|
-
test << p
|
|
3384
|
-
else
|
|
3385
|
-
out parser_error("bad argument #{p.inspect} in eval")
|
|
3386
|
-
return nil
|
|
3387
|
-
end
|
|
3388
|
-
end
|
|
3389
|
-
begin
|
|
3390
|
-
begin
|
|
3391
|
-
eval test.join(' ')
|
|
3392
|
-
rescue
|
|
3393
|
-
# rescue evaluation error
|
|
3394
|
-
out parser_error("error in eval")
|
|
3395
|
-
return nil
|
|
3396
|
-
end
|
|
3397
|
-
"(#{res.join(' ')})"
|
|
3398
|
-
rescue SyntaxError => err
|
|
3399
|
-
# rescue compilation error
|
|
3400
|
-
out parser_error("compilation error in eval")
|
|
3401
|
-
return nil
|
|
3402
|
-
end
|
|
3403
|
-
end
|
|
3404
|
-
|
|
3405
|
-
def find_stored(klass, key)
|
|
3406
|
-
if "#{klass}_#{key}" == "Node_start_node"
|
|
3407
|
-
# main node before ajax stuff (the one in browser url)
|
|
3408
|
-
"start_node"
|
|
3409
|
-
else
|
|
3410
|
-
@context["#{klass}_#{key}"]
|
|
3411
|
-
end
|
|
3412
|
-
end
|
|
3413
|
-
|
|
3414
|
-
def set_stored(klass, key, obj)
|
|
3415
|
-
@context["#{klass}_#{key}"] = obj
|
|
3416
|
-
end
|
|
3417
|
-
|
|
3418
|
-
# transform a 'show' tag into an input field.
|
|
3419
|
-
def make_input(params = @params)
|
|
3420
|
-
input, attribute = get_input_params(params)
|
|
3421
|
-
return parser_error("missing 'name'") unless attribute
|
|
3422
|
-
return '' if attribute == 'parent_id' # set with 'r_form'
|
|
3423
|
-
return '' if ['url','path'].include?(attribute) # cannot be set with a form
|
|
3424
|
-
if params[:date]
|
|
3425
|
-
input_id = @context[:dom_prefix] ? ", :id=>\"#{dom_id}_#{attribute}\"" : ''
|
|
3426
|
-
return "<%= date_box('#{base_class.to_s.underscore}', #{params[:date].inspect}#{input_id}) %>"
|
|
3427
|
-
end
|
|
3428
|
-
input_id = @context[:dom_prefix] ? " id='#{erb_dom_id}_#{attribute}'" : ''
|
|
3429
|
-
"<input type='#{params[:type] || 'text'}'#{input_id} name='#{input[:name]}' value=#{input[:value]}/>"
|
|
3430
|
-
end
|
|
3431
|
-
|
|
3432
|
-
# transform a 'zazen' tag into a textarea input field.
|
|
3433
|
-
def make_textarea(params)
|
|
3434
|
-
return parser_error("missing 'name'") unless name = params[:name]
|
|
3435
|
-
if name =~ /\A([\w_]+)\[(.*?)\]/
|
|
3436
|
-
attribute = $2
|
|
3437
|
-
else
|
|
3438
|
-
attribute = name
|
|
3439
|
-
name = "#{base_class.to_s.underscore}[#{attribute}]"
|
|
3440
|
-
end
|
|
3441
|
-
return '' if attribute == 'parent_id' # set with 'r_form'
|
|
3442
|
-
|
|
3443
|
-
if @blocks == [] || @blocks == ['']
|
|
3444
|
-
if @context[:in_add]
|
|
3445
|
-
value = ''
|
|
3446
|
-
else
|
|
3447
|
-
value = attribute ? "<%= #{node_attribute(attribute)} %>" : ""
|
|
3448
|
-
end
|
|
3449
|
-
else
|
|
3450
|
-
value = expand_with
|
|
3451
|
-
end
|
|
3452
|
-
html_id = @context[:dom_prefix] ? " id='#{erb_dom_id}_#{attribute}'" : ''
|
|
3453
|
-
"<textarea#{html_id} name='#{name}'>#{value}</textarea>"
|
|
3454
|
-
end
|
|
3455
|
-
|
|
3456
|
-
def default_focus_field
|
|
3457
|
-
if (input_fields = descendants('input')) != []
|
|
3458
|
-
field = input_fields.first.params[:name]
|
|
3459
|
-
elsif (show_fields = descendants('show')) != []
|
|
3460
|
-
field = show_fields.first.params[:attr]
|
|
3461
|
-
elsif node_kind_of?(Node)
|
|
3462
|
-
field = 'v_title'
|
|
3463
|
-
else
|
|
3464
|
-
field = 'text'
|
|
3465
|
-
end
|
|
3466
|
-
end
|
|
3467
|
-
|
|
3468
|
-
# Returns true if a form/edit needs to keep track of link_id (l_status or l_comment used).
|
|
3469
|
-
def need_link_id
|
|
3470
|
-
if (input_fields = (descendants('input') + descendants('select'))) != []
|
|
3471
|
-
input_fields.each do |f|
|
|
3472
|
-
return true if f.params[:name] =~ /\Al_/
|
|
3473
|
-
end
|
|
3474
|
-
elsif (show_fields = descendants('show')) != []
|
|
3475
|
-
show_fields.each do |f|
|
|
3476
|
-
return true if f.params[:attr] =~ /\Al_/
|
|
3477
|
-
end
|
|
3478
|
-
end
|
|
3479
|
-
return false
|
|
3480
|
-
end
|
|
3481
|
-
|
|
3482
|
-
def start_node_s_param(type = :input)
|
|
3483
|
-
if type == :input
|
|
3484
|
-
"<input type='hidden' name='s' value='<%= params[:s] || @node[:zip] %>'/>"
|
|
3485
|
-
elsif type == :erb
|
|
3486
|
-
"s=<%= params[:s] || @node[:zip] %>"
|
|
3487
|
-
elsif type == :value
|
|
3488
|
-
"<%= params[:s] || @node[:zip] %>"
|
|
3489
|
-
else
|
|
3490
|
-
"s=\#{params[:s] || @node[:zip]}"
|
|
3491
|
-
end
|
|
3492
|
-
end
|
|
3493
|
-
|
|
3494
|
-
def parser_error(message, tag=@method)
|
|
3495
|
-
"<span class='parser_error'>[#{tag}] #{message}</span>"
|
|
3496
|
-
end
|
|
3497
|
-
|
|
3498
|
-
# Used by [each] and [draggable] to insert 'id' and drag handle span
|
|
3499
|
-
def set_drag_handle_and_id(text, params, id_hash)
|
|
3500
|
-
res, drag_handle = text, nil
|
|
3501
|
-
if params[:drag_handle]
|
|
3502
|
-
drag_handle = params[:drag_handle] == 'true' ? 'drag_handle' : params[:drag_handle]
|
|
3503
|
-
if text =~ /class\s*=\s*['"]#{drag_handle}/
|
|
3504
|
-
# nothing to do
|
|
3505
|
-
insert = ''
|
|
3506
|
-
else
|
|
3507
|
-
insert = "<span class='#{drag_handle}'> </span>"
|
|
3508
|
-
end
|
|
3509
|
-
else
|
|
3510
|
-
insert = ''
|
|
3511
|
-
end
|
|
3512
|
-
|
|
3513
|
-
res = insert + text
|
|
3514
|
-
|
|
3515
|
-
if id_hash
|
|
3516
|
-
@html_tag ||= 'div'
|
|
3517
|
-
@html_tag_params.merge!(id_hash)
|
|
3518
|
-
end
|
|
3519
|
-
|
|
3520
|
-
[res, drag_handle]
|
|
3521
|
-
end
|
|
3522
|
-
|
|
3523
|
-
def expand_with(acontext={})
|
|
3524
|
-
# set variables
|
|
3525
|
-
context = nil
|
|
3526
|
-
pre = ''
|
|
3527
|
-
@blocks.each do |block|
|
|
3528
|
-
next if block.kind_of?(String) || block.method != 'set'
|
|
3529
|
-
@context[:vars] ||= []
|
|
3530
|
-
context ||= @context.merge(acontext).merge(:set => true)
|
|
3531
|
-
pre << expand_block(block, context)
|
|
3532
|
-
@context[:vars] << block.params[:var]
|
|
3533
|
-
end
|
|
3534
|
-
|
|
3535
|
-
pre + super
|
|
3536
|
-
end
|
|
3537
|
-
|
|
3538
|
-
def auto_publish_param(in_string = false)
|
|
3539
|
-
if in_string
|
|
3540
|
-
['true','force'].include?(@params[:publish]) ? "&publish=#{@params[:publish]}" : ''
|
|
3541
|
-
else
|
|
3542
|
-
@params[:publish]
|
|
3543
|
-
end
|
|
3544
|
-
end
|
|
3545
|
-
|
|
3546
|
-
# This is used by zafu and it's a mess.
|
|
3547
|
-
# ref_date can be a string ('2005-05-03') or ruby ('Time.now'). It should not come uncleaned from evil web.
|
|
3548
|
-
def date_condition(date_cond, field, ref_date='today')
|
|
3549
|
-
if date_cond == 'today' || ref_date == 'today'
|
|
3550
|
-
ref_date = Zena::Db::NOW
|
|
3551
|
-
elsif ref_date =~ /(\d{4}-\d{1,2}-\d{1,2}( \d{1,2}:\d{1,2}(:\d{1,2})?)?)/
|
|
3552
|
-
ref_date = "'#{$1}'"
|
|
3553
|
-
elsif ref_date =~ /\A"/
|
|
3554
|
-
ref_date = "'\#{format_date(#{ref_date})}'"
|
|
3555
|
-
else
|
|
3556
|
-
ref_date = "'\#{#{ref_date}.strftime('%Y-%m-%d %H:%M:%S')}'"
|
|
3557
|
-
end
|
|
3558
|
-
Zena::Db.date_condition(date_cond, field, ref_date)
|
|
3559
|
-
end
|
|
3560
|
-
end # ZenaTags
|
|
3561
|
-
end # Parser
|
|
3562
|
-
end # Zena
|