zena 1.0.0.beta3 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +29 -0
- data/Rakefile +2 -0
- data/TODO_ZENA_1_0 +13 -23
- data/app/controllers/columns_controller.rb +1 -1
- data/app/controllers/comments_controller.rb +4 -3
- data/app/controllers/documents_controller.rb +8 -11
- data/app/controllers/nodes_controller.rb +39 -21
- data/app/controllers/users_controller.rb +8 -3
- data/app/controllers/versions_controller.rb +2 -2
- data/app/controllers/virtual_classes_controller.rb +17 -11
- data/app/helpers/documents_helper.rb +0 -3
- data/app/helpers/users_helper.rb +17 -0
- data/app/models/cache.rb +36 -31
- data/app/models/column.rb +48 -5
- data/app/models/comment.rb +14 -5
- data/app/models/data_entry.rb +2 -2
- data/app/models/document.rb +23 -33
- data/app/models/idx_nodes_datetime.rb +4 -0
- data/app/models/idx_nodes_float.rb +4 -0
- data/app/models/idx_project.rb +3 -0
- data/app/models/node.rb +372 -308
- data/app/models/page.rb +1 -31
- data/app/models/relation.rb +4 -4
- data/app/models/relation_proxy.rb +128 -17
- data/app/models/role.rb +27 -2
- data/app/models/site.rb +64 -56
- data/app/models/template.rb +11 -12
- data/app/models/text_document.rb +6 -7
- data/app/models/user.rb +95 -46
- data/app/models/version.rb +2 -2
- data/app/models/virtual_class.rb +418 -73
- data/app/views/columns/_form.html.erb +1 -1
- data/app/views/columns/_li.html.erb +1 -1
- data/app/views/comments/_form.rhtml +1 -1
- data/app/views/comments/_li.rhtml +1 -1
- data/app/views/comments/_li_simple.rhtml +1 -1
- data/app/views/groups/_form.rhtml +1 -1
- data/app/views/links/_li.rhtml +1 -1
- data/app/views/nodes/_groups.rhtml +1 -1
- data/app/views/nodes/_import_results.rhtml +1 -1
- data/app/views/nodes/_parent.rhtml +1 -1
- data/app/views/nodes/_results.rhtml +1 -1
- data/app/views/nodes/create.rjs +4 -2
- data/app/views/relations/_li.erb +2 -2
- data/app/views/templates/document_create_tabs/_file.rhtml +1 -1
- data/app/views/templates/document_create_tabs/_template.rhtml +2 -2
- data/app/views/templates/document_create_tabs/_text_document.rhtml +2 -2
- data/app/views/templates/edit_tabs/_help.rhtml +1 -1
- data/app/views/templates/edit_tabs/_title.rhtml +0 -3
- data/app/views/users/_form.rhtml +2 -6
- data/app/views/users/_li.rhtml +1 -3
- data/app/views/users/create.rjs +4 -4
- data/app/views/users/preferences.html.erb +1 -4
- data/app/views/versions/custom_tab.rhtml +5 -0
- data/app/views/virtual_classes/_form.erb +20 -10
- data/app/views/virtual_classes/_li.erb +21 -8
- data/app/views/zafu/default/Node-+search.zafu +1 -1
- data/app/views/zafu/default/Node.zafu +3 -3
- data/bricks/captcha/lib/bricks/captcha.rb +1 -1
- data/bricks/mongrel/zena/deploy.rb +14 -0
- data/bricks/{data2pdf → pdf}/.document +0 -0
- data/bricks/pdf/README +33 -0
- data/bricks/{data2pdf → pdf}/Rakefile +0 -0
- data/bricks/pdf/VERSION +1 -0
- data/bricks/pdf/lib/bricks/pdf.rb +110 -0
- data/bricks/pdf/lib/bricks/pdf/engine/prince.rb +38 -0
- data/bricks/pdf/lib/bricks/pdf/engine/xhtml2pdf.rb +9 -0
- data/bricks/pdf/lib/bricks/pdf/install.rb +121 -0
- data/bricks/pdf/test/engines/test_prince.rb +15 -0
- data/bricks/pdf/test/engines/test_xhtml2pdf.rb +15 -0
- data/bricks/{data2pdf → pdf}/test/fixtures/application.css +0 -0
- data/bricks/{data2pdf → pdf}/test/fixtures/contact.html +0 -0
- data/bricks/{data2pdf → pdf}/test/fixtures/pisa-default.css +0 -0
- data/bricks/{data2pdf → pdf}/test/fixtures/sheet1.css +0 -0
- data/bricks/{data2pdf → pdf}/test/fixtures/sheet2.css +0 -0
- data/bricks/{data2pdf → pdf}/test/fixtures/simple-html.html +0 -0
- data/bricks/{data2pdf → pdf}/test/fixtures/simple-text.txt +0 -0
- data/bricks/{data2pdf → pdf}/test/helper.rb +4 -5
- data/bricks/pdf/test/shoulda_macros/shoulda_pdf.rb +72 -0
- data/bricks/pdf/zena/init.rb +5 -0
- data/bricks/pdf/zena/tasks.rb +17 -0
- data/bricks/sphinx/lib/{use_sphinx.rb → bricks/sphinx.rb} +1 -1
- data/bricks/tags/zena/init.rb +2 -2
- data/bricks/tags/zena/test/zafu/tags.yml +4 -4
- data/bricks/zena/zena/migrate/01_base.rb +482 -0
- data/config/bricks.yml +22 -6
- data/config/gems.yml +8 -6
- data/db/20100628074512_zena0x_to1x.rb +6 -1
- data/db/fix/024_correct_vclass_kpath.rb +11 -0
- data/db/fix/025_move_tag_into_vclass.rb +13 -0
- data/db/{migrate → fix}/026_rename_templates.rb +0 -0
- data/db/{migrate → fix}/045_avoid_star_in_templates.rb +0 -0
- data/db/{migrate → fix}/046_fix_zazen_image_tag.rb +0 -0
- data/db/{migrate → fix}/047_change_default_link_id_to_zero.rb +1 -3
- data/db/{migrate → fix}/049_fix_publish_from_is_null.rb +0 -0
- data/db/{migrate → fix}/20090924141459_zafu_fix_sept09.rb +0 -0
- data/db/{migrate → fix}/20091013100351_rename_publish_group_to_drive_group.rb +1 -3
- data/db/{migrate → fix}/20091124161608_rebuild_fullpath.rb +0 -1
- data/db/{migrate → fix}/20100115134729_rebuild_fullpath_after_fix.rb +0 -0
- data/db/{migrate → fix}/20100526090140_renamed_contact_model_to_base_contact.rb +2 -4
- data/db/{migrate → fix/old_migrations}/001_create_base.rb +0 -1
- data/db/{migrate → fix/old_migrations}/002_add_time_zone_to_users.rb +0 -0
- data/db/{migrate → fix/old_migrations}/003_add_custom_base_flag.rb +0 -0
- data/db/{migrate → fix/old_migrations}/004_rename_template_skin.rb +0 -0
- data/db/{migrate → fix/old_migrations}/005_create_cached_pages.rb +0 -0
- data/db/{migrate → fix/old_migrations}/006_create_sites.rb +0 -0
- data/db/{migrate → fix/old_migrations}/007_replace_id_by_zip.rb +0 -0
- data/db/{migrate → fix/old_migrations}/008_user_status.rb +0 -0
- data/db/{migrate → fix/old_migrations}/009_fulltext.rb +0 -0
- data/db/fix/old_migrations/010_create_template_content.rb +17 -0
- data/db/{migrate → fix/old_migrations}/011_project_to_section.rb +0 -0
- data/db/{migrate → fix/old_migrations}/012_add_project_id.rb +0 -0
- data/db/{migrate → fix/old_migrations}/013_remove_defaults.rb +0 -0
- data/db/{migrate → fix/old_migrations}/014_add_sort_field.rb +0 -0
- data/db/{migrate → fix/old_migrations}/015_add_dyn_attributes.rb +0 -0
- data/db/{migrate → fix/old_migrations}/016_remove_translations.rb +0 -0
- data/db/{migrate → fix/old_migrations}/017_rename_authorize.rb +0 -0
- data/db/{migrate → fix/old_migrations}/018_add_auth_option.rb +0 -0
- data/db/{migrate → fix/old_migrations}/019_remove_user_status.rb +0 -0
- data/db/{migrate → fix/old_migrations}/020_create_participation.rb +0 -0
- data/db/{migrate → fix/old_migrations}/021_create_relations.rb +0 -0
- data/db/{migrate → fix/old_migrations}/022_create_virtual_classes.rb +0 -0
- data/db/{migrate → fix/old_migrations}/023_ip_on_anonymous_comment.rb +0 -0
- data/db/{migrate → fix/old_migrations}/027_add_country_to_contacts.rb +0 -0
- data/db/{migrate → fix/old_migrations}/028_change_size_of_conten_type_field.rb +0 -0
- data/db/{migrate → fix/old_migrations}/029_create_data_entries.rb +0 -0
- data/db/{migrate → fix/old_migrations}/030_redit_auto_publish_site_settings.rb +0 -0
- data/db/{migrate → fix/old_migrations}/031_create_iformats.rb +0 -0
- data/db/{migrate → fix/old_migrations}/032_caches_context_as_hash.rb +0 -0
- data/db/{migrate → fix/old_migrations}/033_documents_kpath_change.rb +0 -0
- data/db/{migrate → fix/old_migrations}/034_change_file_storage.rb +0 -0
- data/db/{migrate → fix/old_migrations}/035_add_status_to_link.rb +0 -0
- data/db/{migrate → fix/old_migrations}/036_add_flag_fields_on_nodes.rb +0 -0
- data/db/{migrate → fix/old_migrations}/037_add_auto_create_discussion_to_v_class.rb +0 -0
- data/db/{migrate → fix/old_migrations}/038_create_site_attributes.rb +0 -0
- data/db/{migrate → fix/old_migrations}/039_default_position.rb +0 -0
- data/db/{migrate → fix/old_migrations}/040_second_value_for_data_entry.rb +0 -0
- data/db/{migrate → fix/old_migrations}/041_add_attributes_to_v_class.rb +0 -0
- data/db/{migrate → fix/old_migrations}/042_fix_position_should_be_float.rb +0 -0
- data/db/{migrate → fix/old_migrations}/043_move_user_lang_into_participation.rb +0 -0
- data/db/{migrate → fix/old_migrations}/044_remove_monolingual_site_option.rb +0 -0
- data/db/{migrate → fix/old_migrations}/048_link_source_target_can_be_null.rb +0 -0
- data/db/{migrate → fix/old_migrations}/050_date_in_links.rb +0 -0
- data/db/{migrate → fix/old_migrations}/051_add_exif_tags_to_images.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20090825201159_insert_zero_link.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20090825201200_merge_bricks_migrations_with_std_migrations.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20090927125912_allow_null_in_text_fields.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20090928133440_no_more_private_nodes.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20090928143754_version_status_change.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20091001084025_change_status_values_for_comments.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20091009084057_add_vhash_in_node.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20091014130833_fix_template_title.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20091014183726_merge_participation_into_users.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20091018200734_add_popup_info_to_image_format.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20091026161708_add_persistence_token.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20091101184952_add_session_table.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20091123175137_add_single_access_token.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100125062254_add_dynamo_to_version.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100201133242_remove_default_status_on_version.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100208194210_create_attachments.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100210112319_change_dynamo_to_property.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100320145726_transform_template_contents_into_index.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100328125634_change_skin_name_to_id.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100417061257_add_properties_to_sites.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100419163149_rename_name_to_node_name.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100422091606_change_v_class_table_into_roles.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100422094048_node_habtm_roles.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100422115935_create_columns.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100513181529_add_site_id_to_columns.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100519091711_add_index_definition_to_columns.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100519091940_create_idx_nodes_string.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100519232432_create_idx_nodes_ml_string.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100525113858_add_porperties_to_users.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100527130937_change_column_index_to_string.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100531135128_add_fulltext_builder_fields.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100915062903_add_api_group_id_to_site.rb +0 -0
- data/db/fix/old_migrations/20100923154807_remove_base_contact.rb +84 -0
- data/db/fix/old_migrations/20100926192223_remove_su_user.rb +8 -0
- data/db/fix/old_migrations/20100927141658_add_eval_attributes_to_v_class.rb +12 -0
- data/db/fix/old_migrations/20100928185257_add_obvious_idx.rb +52 -0
- data/db/fix/old_migrations/20100929143111_remove_node_name.rb +11 -0
- data/db/fix/old_migrations/20101006090454_store_properties_in_long_text.rb +9 -0
- data/db/fix/old_migrations/20101014185753_remove_user_prototype_id.rb +9 -0
- data/db/fix/old_migrations/20101101084318_create_scope_index.rb +35 -0
- data/db/fix/old_migrations/20101109074232_create_idx_nodes_tables.rb +65 -0
- data/db/fix/old_migrations/20101110184235_add_role_update_to_site.rb +9 -0
- data/db/fix/old_migrations/20101116103920_change_scope_index.rb +31 -0
- data/db/fix/old_migrations/20101123125822_add_integer_idx.rb +17 -0
- data/db/fix/old_migrations/20101130134522_add_index_field.rb +13 -0
- data/db/fix/old_migrations/20101213133816_add_group_to_relation.rb +9 -0
- data/db/init/base/help.fr.zml +1 -1
- data/db/init/base/skins/default.zml +0 -1
- data/db/init/base/skins/default/Node-+search.zafu +1 -1
- data/db/init/base/skins/default/Node-tree.zafu +3 -3
- data/db/init/base/skins/default/Node.zafu +3 -3
- data/lib/bricks/loader.rb +4 -1
- data/lib/bricks/requirements_validation.rb +11 -6
- data/lib/log_recorder/lib/log_recorder.rb +2 -2
- data/lib/tasks/zena.rake +25 -15
- data/lib/zena.rb +42 -9
- data/lib/zena/acts/enrollable.rb +81 -99
- data/lib/zena/acts/secure.rb +27 -23
- data/lib/zena/acts/secure_node.rb +10 -55
- data/lib/zena/acts/serializable.rb +9 -10
- data/lib/zena/app.rb +0 -2
- data/lib/zena/code_syntax.rb +1 -1
- data/lib/zena/controller/test_case.rb +0 -5
- data/lib/zena/core_ext/string.rb +48 -20
- data/lib/zena/db.rb +10 -442
- data/lib/zena/db_helper/abstract_db.rb +184 -0
- data/lib/zena/db_helper/mysql.rb +150 -0
- data/lib/zena/db_helper/postgresql.rb +79 -0
- data/lib/zena/db_helper/sqlite3.rb +135 -0
- data/lib/zena/deploy.rb +4 -1
- data/lib/zena/deploy/httpd.rhtml +3 -3
- data/lib/zena/deploy/vhost.rhtml +1 -1
- data/lib/zena/foxy_parser.rb +37 -18
- data/lib/zena/info.rb +3 -13
- data/lib/zena/migrator.rb +0 -1
- data/lib/zena/parser/zafu_rules.rb +9 -4
- data/lib/zena/parser/zazen_rules.rb +5 -5
- data/lib/zena/parser/zena_rules.rb +1 -1
- data/lib/zena/remote/interface.rb +1 -1
- data/lib/zena/site_worker.rb +3 -3
- data/lib/zena/test_controller.rb +10 -10
- data/lib/zena/use/action.rb +66 -6
- data/lib/zena/use/ajax.rb +39 -13
- data/lib/zena/use/ancestry.rb +210 -0
- data/lib/zena/use/authlogic.rb +30 -1
- data/lib/zena/use/calendar.rb +158 -0
- data/lib/zena/use/conditional.rb +3 -2
- data/lib/zena/use/context.rb +42 -12
- data/lib/zena/use/dates.rb +15 -14
- data/lib/zena/use/display.rb +54 -7
- data/lib/zena/use/error_rendering.rb +1 -0
- data/lib/zena/use/field_index.rb +20 -0
- data/lib/zena/use/fixtures.rb +12 -9
- data/lib/zena/use/forms.rb +230 -106
- data/lib/zena/use/fulltext.rb +28 -14
- data/lib/zena/use/html_tags.rb +1 -24
- data/lib/zena/use/i18n.rb +69 -14
- data/lib/zena/use/kpath.rb +60 -0
- data/lib/zena/use/ml_index.rb +6 -4
- data/lib/zena/use/node_context.rb +63 -0
- data/lib/zena/use/prop_eval.rb +90 -0
- data/lib/zena/use/query_builder.rb +159 -29
- data/lib/zena/use/query_comment.rb +1 -1
- data/lib/zena/use/query_node.rb +147 -56
- data/lib/zena/use/recursion.rb +2 -2
- data/lib/zena/use/relations.rb +31 -19
- data/lib/zena/use/rendering.rb +111 -121
- data/lib/zena/use/scope_index.rb +230 -0
- data/lib/zena/use/search.rb +7 -7
- data/lib/zena/use/urls.rb +87 -25
- data/lib/zena/use/version_hash.rb +113 -113
- data/lib/zena/use/workflow.rb +5 -1
- data/lib/zena/use/zafu_attributes.rb +11 -14
- data/lib/zena/use/zafu_eval.rb +1 -1
- data/lib/zena/use/zafu_safe_definitions.rb +91 -9
- data/lib/zena/use/zafu_templates.rb +146 -102
- data/lib/zena/use/zazen.rb +5 -4
- data/lib/zena/zafu_compiler.rb +1 -0
- data/locale/en/LC_MESSAGES/zena.mo +0 -0
- data/locale/en/zena.po +0 -1
- data/locale/fr/LC_MESSAGES/zena.mo +0 -0
- data/locale/fr/zena.mo +0 -0
- data/locale/fr/zena.po +4 -4
- data/misc/zena +35 -0
- data/misc/zena_init +41 -0
- data/public/images/ext/{basecontact.png → contact.png} +0 -0
- data/public/javascripts/zena.js +35 -7
- data/public/stylesheets/admin.css +5 -2
- data/public/stylesheets/default.css +2 -1
- data/public/stylesheets/popup.css +1 -1
- data/public/stylesheets/zena.css +2 -2
- data/test/custom_queries/complex.host.yml +12 -5
- data/test/fixtures/files/Node-test.zafu +3 -3
- data/test/fixtures/files/translations_fr.yml +4 -2
- data/test/functional/documents_controller_test.rb +31 -0
- data/test/functional/nodes_controller_commit_test.rb +1 -5
- data/test/functional/nodes_controller_test.rb +92 -12
- data/test/functional/user_sessions_controller_test.rb +2 -2
- data/test/functional/users_controller_test.rb +31 -29
- data/test/functional/versions_controller_test.rb +2 -2
- data/test/functional/virtual_classes_controller_test.rb +2 -2
- data/test/integration/multiple_hosts_test.rb +19 -8
- data/test/integration/navigation_test.rb +91 -12
- data/test/integration/query_node/basic.yml +40 -37
- data/test/integration/query_node/complex.yml +23 -18
- data/test/integration/query_node/dates.yml +3 -3
- data/test/integration/query_node/errors.yml +7 -1
- data/test/integration/query_node/filters.yml +41 -35
- data/test/integration/query_node/idx_fields.yml +11 -0
- data/test/integration/query_node/idx_key_value.yml +77 -0
- data/test/integration/query_node/idx_scope.yml +33 -0
- data/test/integration/query_node/relations.yml +13 -13
- data/test/integration/query_node_test.rb +6 -10
- data/test/integration/zafu_compiler/action.yml +19 -6
- data/test/integration/zafu_compiler/ajax.yml +111 -51
- data/test/integration/zafu_compiler/apphelper.yml +1 -1
- data/test/integration/zafu_compiler/asset.yml +1 -1
- data/test/integration/zafu_compiler/basic.yml +42 -52
- data/test/integration/zafu_compiler/calendar.yml +3 -3
- data/test/integration/zafu_compiler/complex.yml +16 -16
- data/test/integration/zafu_compiler/complex_ok.yml +2 -2
- data/test/integration/zafu_compiler/conditional.yml +42 -33
- data/test/integration/zafu_compiler/data.yml +3 -3
- data/test/integration/zafu_compiler/dates.yml +25 -10
- data/test/integration/zafu_compiler/display.yml +49 -12
- data/test/integration/zafu_compiler/errors.yml +26 -6
- data/test/integration/zafu_compiler/eval.yml +4 -4
- data/test/integration/zafu_compiler/forms.yml +89 -15
- data/test/integration/zafu_compiler/i18n.yml +23 -18
- data/test/integration/zafu_compiler/idx_scope.yml +7 -0
- data/test/integration/zafu_compiler/later.yml +10 -16
- data/test/integration/zafu_compiler/off/off.yml +2 -2
- data/test/integration/zafu_compiler/query.yml +207 -0
- data/test/integration/zafu_compiler/recursion.yml +2 -2
- data/test/integration/zafu_compiler/relations.yml +144 -168
- data/test/integration/zafu_compiler/roles.yml +86 -10
- data/test/integration/zafu_compiler/rubyless.yml +49 -6
- data/test/integration/zafu_compiler/safe_definitions.yml +35 -6
- data/test/integration/zafu_compiler/search.yml +1 -1
- data/test/integration/zafu_compiler/security.yml +37 -0
- data/test/integration/zafu_compiler/urls.yml +50 -40
- data/test/integration/zafu_compiler/user.yml +21 -6
- data/test/integration/zafu_compiler/version.yml +6 -6
- data/test/integration/zafu_compiler/zafu_attributes.yml +43 -34
- data/test/integration/zafu_compiler/zazen.yml +10 -10
- data/test/integration/zafu_compiler_test.rb +19 -13
- data/test/sites/complex/nodes.yml +0 -2
- data/test/sites/complex/roles.yml +9 -1
- data/test/sites/complex/sites.yml +0 -1
- data/test/sites/complex/users.yml +2 -5
- data/test/sites/ocean/nodes.yml +2 -5
- data/test/sites/ocean/roles.yml +8 -0
- data/test/sites/ocean/sites.yml +0 -1
- data/test/sites/ocean/users.yml +0 -13
- data/test/sites/zena/columns.yml +27 -5
- data/test/sites/zena/idx_projects.yml +5 -0
- data/test/sites/zena/nodes.yml +8 -32
- data/test/sites/zena/relations.yml +5 -0
- data/test/sites/zena/roles.yml +25 -3
- data/test/sites/zena/sites.yml +2 -2
- data/test/sites/zena/users.yml +1 -21
- data/test/sites/zena/versions.yml +35 -12
- data/test/test_helper.rb +7 -0
- data/test/unit/after_commit_test.rb +7 -7
- data/test/unit/cache_test.rb +32 -0
- data/test/unit/cached_page_test.rb +1 -1
- data/test/unit/column_test.rb +31 -7
- data/test/unit/comment_test.rb +2 -2
- data/test/unit/core_ext_test.rb +38 -7
- data/test/unit/document_test.rb +14 -42
- data/test/unit/node_test.rb +311 -324
- data/test/unit/note_test.rb +23 -31
- data/test/unit/page_test.rb +16 -58
- data/test/unit/project_test.rb +2 -2
- data/test/unit/relation_proxy_test.rb +148 -21
- data/test/unit/relation_test.rb +23 -3
- data/test/unit/remote_test.rb +15 -9
- data/test/unit/role_test.rb +9 -0
- data/test/unit/site_test.rb +49 -47
- data/test/unit/skin_test.rb +16 -0
- data/test/unit/template_test.rb +60 -69
- data/test/unit/text_document_test.rb +15 -14
- data/test/unit/user_test.rb +101 -41
- data/test/unit/version_test.rb +4 -4
- data/test/unit/virtual_class_test.rb +577 -36
- data/test/unit/workflow_test.rb +58 -21
- data/test/unit/zena/acts/enrollable_test.rb +36 -127
- data/test/unit/zena/acts/secure_test.rb +6 -22
- data/test/unit/zena/acts/serializable_test.rb +18 -0
- data/test/unit/zena/db_test.rb +14 -14
- data/test/unit/zena/parser/zafu.yml +5 -3
- data/test/unit/zena/use/ancestry_test.rb +198 -0
- data/test/unit/zena/use/calendar_test.rb +8 -8
- data/test/unit/zena/use/dates_test.rb +2 -0
- data/test/unit/zena/use/fulltext_test.rb +9 -1
- data/test/unit/zena/use/html_tags_test.rb +2 -16
- data/test/unit/zena/use/i18n_test.rb +2 -2
- data/test/unit/zena/use/kpath_test.rb +13 -0
- data/test/unit/zena/use/ml_index_test.rb +60 -12
- data/test/unit/zena/use/prop_eval_test.rb +170 -0
- data/test/unit/zena/use/query_node_test.rb +9 -2
- data/test/unit/zena/use/rendering_test.rb +98 -1
- data/test/unit/zena/use/scope_index_test.rb +464 -0
- data/test/unit/zena/use/urls_test.rb +23 -13
- data/test/unit/zena/use/version_hash_test.rb +2 -2
- data/test/unit/zena/use/zafu_template_test.rb +21 -8
- data/test/unit/zena/use/zazen_test.rb +47 -47
- data/zena.gemspec +177 -143
- metadata +222 -141
- data/app/models/base_contact.rb +0 -79
- data/app/models/book.rb +0 -242
- data/app/models/contact_content.rb +0 -70
- data/app/models/contact_version.rb +0 -40
- data/app/models/reference.rb +0 -18
- data/app/views/templates/edit_tabs/_basecontact.rhtml +0 -8
- data/bricks/data2pdf/README +0 -19
- data/bricks/data2pdf/VERSION +0 -1
- data/bricks/data2pdf/lib/data2pdf.rb +0 -60
- data/bricks/data2pdf/lib/engines/prince.rb +0 -39
- data/bricks/data2pdf/lib/engines/xhtml2pdf.rb +0 -41
- data/bricks/data2pdf/lib/install.rb +0 -111
- data/bricks/data2pdf/test/engines/test_prince.rb +0 -14
- data/bricks/data2pdf/test/engines/test_xhtml2pdf.rb +0 -14
- data/bricks/data2pdf/test/shoulda_macros/shoulda_data2pdf.rb +0 -91
- data/bricks/data2pdf/test/unit/test_rendering.rb +0 -37
- data/config/routes.rb +0 -3
- data/db/migrate/010_create_template_content.rb +0 -17
- data/db/migrate/024_correct_vclass_kpath.rb +0 -13
- data/db/migrate/025_move_tag_into_vclass.rb +0 -15
- data/lib/version_off.rb +0 -323
- data/lib/zena/use/node_name.rb +0 -94
- data/test/integration/query_node/properties.yml +0 -41
- data/test/unit/base_contact_test.rb +0 -242
- data/test/unit/node_name_test.rb +0 -137
data/lib/zena/use/conditional.rb
CHANGED
@@ -2,6 +2,7 @@ module Zena::Use::Conditional
|
|
2
2
|
module ZafuMethods
|
3
3
|
|
4
4
|
def rubyless_class_scope(class_name)
|
5
|
+
return parser_error("Cannot scope class in list (use each before filtering).") if node.list_context?
|
5
6
|
# capital letter ==> class conditional
|
6
7
|
if klass = get_class(class_name)
|
7
8
|
if klass.kpath =~ %r{^#{node.klass.kpath}} || @context[:saved_template]
|
@@ -19,11 +20,11 @@ module Zena::Use::Conditional
|
|
19
20
|
# Saved templates can be rendered with anything...
|
20
21
|
# FIXME: Make sure saved templates from 'block' start with the proper node type ?
|
21
22
|
cond = "#{node}.has_role?(#{role.id})"
|
22
|
-
new_node = node.move_to(node.name, klass)
|
23
|
+
new_node = node.move_to(node.name, node.klass)
|
23
24
|
else
|
24
25
|
# render nothing: incompatible classes
|
25
26
|
cond = 'false'
|
26
|
-
new_node = node.move_to(node.name, klass)
|
27
|
+
new_node = node.move_to(node.name, node.klass)
|
27
28
|
end
|
28
29
|
else
|
29
30
|
return parser_error("Invalid role or class '#{class_name}'")
|
data/lib/zena/use/context.rb
CHANGED
@@ -2,12 +2,26 @@ module Zena
|
|
2
2
|
module Use
|
3
3
|
module Context
|
4
4
|
module ViewMethods
|
5
|
+
|
6
|
+
# Dynamic resolution of the author class from the user prototype
|
7
|
+
def self.visitor_node_proc
|
8
|
+
Proc.new do |h, r, s|
|
9
|
+
res = {:method => 'visitor.node', :nil => true}
|
10
|
+
if prototype = visitor.prototype
|
11
|
+
res[:class] = prototype.vclass
|
12
|
+
else
|
13
|
+
res[:class] = VirtualClass['Node']
|
14
|
+
end
|
15
|
+
res
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
5
19
|
include RubyLess
|
6
|
-
safe_method :start => {:method => 'start_node', :class => Node}
|
20
|
+
safe_method :start => Proc.new {|h, r, s| {:method => 'start_node', :class => VirtualClass['Node']}}
|
7
21
|
safe_method :visitor => User
|
8
|
-
safe_method :visitor_node =>
|
9
|
-
safe_method :main => {:method => '@node', :class => Node}
|
10
|
-
safe_method :root => {:method => 'visitor.site.root_node', :class => Node, :nil => true}
|
22
|
+
safe_method :visitor_node => visitor_node_proc
|
23
|
+
safe_method :main => Proc.new {|h, r, s| {:method => '@node', :class => VirtualClass['Node']}}
|
24
|
+
safe_method :root => Proc.new {|h, r, s| {:method => 'visitor.site.root_node', :class => VirtualClass['Node'], :nil => true}}
|
11
25
|
safe_method :site => {:class => Site, :method => 'visitor.site'}
|
12
26
|
|
13
27
|
# Group an array of records by key.
|
@@ -98,21 +112,30 @@ module Zena
|
|
98
112
|
join_str = ''
|
99
113
|
if count <= max_count
|
100
114
|
1.upto(count) do |p|
|
101
|
-
yield(p, join_str)
|
115
|
+
yield(p, join_str, p)
|
102
116
|
join_str = join_string
|
103
117
|
end
|
104
118
|
else
|
105
119
|
# only first pages (centered around current page)
|
106
120
|
if current - (max_count/2) > 0
|
107
|
-
|
121
|
+
max = current + (max_count/2)
|
108
122
|
else
|
109
|
-
|
123
|
+
max = max_count
|
124
|
+
end
|
125
|
+
|
126
|
+
if count > max
|
127
|
+
finish = end_dots = max
|
128
|
+
else
|
129
|
+
finish = count
|
110
130
|
end
|
111
131
|
|
112
132
|
start = [finish - max_count + 1,1].max
|
133
|
+
if start > 1
|
134
|
+
start_dots = start
|
135
|
+
end
|
113
136
|
|
114
137
|
start.upto(finish) do |p|
|
115
|
-
yield(p, join_str)
|
138
|
+
yield(p, join_str, (p == start_dots || p == end_dots) ? '…' : p.to_s)
|
116
139
|
join_str = join_string
|
117
140
|
end
|
118
141
|
end
|
@@ -121,6 +144,13 @@ module Zena
|
|
121
144
|
|
122
145
|
module ZafuMethods
|
123
146
|
|
147
|
+
# Resolve class for @post ==> Post, etc.
|
148
|
+
def get_class(class_name)
|
149
|
+
VirtualClass[class_name] || super
|
150
|
+
rescue
|
151
|
+
nil
|
152
|
+
end
|
153
|
+
|
124
154
|
# Enter a new context (<r:context find='all' select='pages'>). This is the same as '<r:pages>...</r:pages>'). It is
|
125
155
|
# considered better style to use '<r:pages>...</r:pages>' instead of the more general '<r:context>' because the tags
|
126
156
|
# give a clue on the context at start and end. Another way to open a context is the 'do' syntax: "<div do='pages'>...</div>".
|
@@ -136,7 +166,7 @@ module Zena
|
|
136
166
|
return parser_error("cannot be used outside of a list") unless node.list_context?
|
137
167
|
return parser_error("missing 'by' clause") unless key = @params[:by]
|
138
168
|
|
139
|
-
#sort_key = @params[:sort] || '
|
169
|
+
#sort_key = @params[:sort] || 'title'
|
140
170
|
# if node.will_be?(DataEntry) && DataEntry::NodeLinkSymbols.include?(key.to_sym)
|
141
171
|
# key = "#{key}_id"
|
142
172
|
# #sort_block = "{|e| (e.#{key} || {})[#{sort_key.to_sym.inspect}]}"
|
@@ -156,11 +186,11 @@ module Zena
|
|
156
186
|
end
|
157
187
|
|
158
188
|
#if sort_block
|
159
|
-
# out "<% grp_#{list_var} = sort_array(#{group_array}) #{sort_block}
|
189
|
+
# out "<% grp_#{list_var} = sort_array(#{group_array}) #{sort_block} %>"
|
160
190
|
#else
|
161
191
|
#end
|
162
192
|
method = "group_array(#{node}) {|e| #{key}}"
|
163
|
-
out "<% if #{var} = #{method}
|
193
|
+
out "<% if #{var} = #{method} %>"
|
164
194
|
open_node_context({:method => method}, :node => node.move_to(var, [node.klass], :query => node.opts[:query])) do
|
165
195
|
if child['each_group']
|
166
196
|
out expand_with
|
@@ -169,7 +199,7 @@ module Zena
|
|
169
199
|
r_each
|
170
200
|
end
|
171
201
|
end
|
172
|
-
out "<% end
|
202
|
+
out "<% end %>"
|
173
203
|
|
174
204
|
#if descendant('each_group')
|
175
205
|
# out expand_with(:group => var)
|
data/lib/zena/use/dates.rb
CHANGED
@@ -5,7 +5,7 @@ module Zena
|
|
5
5
|
|
6
6
|
# This is like strftime but with better support for i18n (translate day names, month abbreviations, etc)
|
7
7
|
def format_date(thedate, opts = {})
|
8
|
-
return ''
|
8
|
+
return '' if thedate.blank?
|
9
9
|
|
10
10
|
theformat, tz_name, lang = opts[:format], opts[:tz], opts[:lang]
|
11
11
|
format = theformat || '%Y-%m-%d %H:%M:%S'
|
@@ -28,10 +28,8 @@ module Zena
|
|
28
28
|
begin
|
29
29
|
adate = Date.parse(thedate)
|
30
30
|
utc_date = adate
|
31
|
-
|
32
31
|
rescue
|
33
|
-
|
34
|
-
return theformat ? "<span class='parser_error'>invalid date #{thedate.inspect}</span>" : Time.now.strftime('%Y-%m-%d %H:%M:%S')
|
32
|
+
return "<span class='parser_error'>invalid date #{thedate.inspect}</span>"
|
35
33
|
end
|
36
34
|
else
|
37
35
|
adate = thedate
|
@@ -116,12 +114,15 @@ module Zena
|
|
116
114
|
rnd_id = rand(100000000000)
|
117
115
|
defaults = { :id=>"datef#{rnd_id}", :button=>"dateb#{rnd_id}", :display=>"dated#{rnd_id}" }
|
118
116
|
opts = defaults.merge(opts)
|
119
|
-
date = obj.
|
117
|
+
date = opts[:value] || obj.safe_send(name)
|
120
118
|
value = tformat_date(date,'datetime')
|
121
|
-
|
122
|
-
|
119
|
+
# TODO: migrate code to Zafu::Markup (needs Zafu 0.7.7)
|
120
|
+
# fld = Zafu::Markup.new('input')
|
121
|
+
# fld.params = (opts[:html] || {}).merge(:name => "node[#{name}]", :id => opts[:id], :type => 'text', :value => value)
|
122
|
+
if opts[:size]
|
123
|
+
fld = "<input id='#{opts[:id]}' name='node[#{name}]' type='text' size='#{opts[:size]}' value='#{value}' class='#{opts[:class]}'/>"
|
123
124
|
else
|
124
|
-
fld = "<input id='#{opts[:id]}' name='node[#{name}]' type='text' value='#{value}' />"
|
125
|
+
fld = "<input id='#{opts[:id]}' name='node[#{name}]' type='text' value='#{value}' class='#{opts[:class]}'/>"
|
125
126
|
end
|
126
127
|
<<-EOL
|
127
128
|
<span class="date_box"><img src="/calendar/iconCalendar.gif" id="#{opts[:button]}" alt='#{_('date selection')}'/>
|
@@ -250,11 +251,11 @@ module Zena
|
|
250
251
|
include RubyLess
|
251
252
|
safe_method_for Time, :year => {:class => Number, :pre_processor => true}
|
252
253
|
safe_method_for Time, [:strftime, String] => {:class => String, :pre_processor => true}
|
253
|
-
safe_method :
|
254
|
+
safe_method :main_date => :get_date
|
254
255
|
safe_method [:parse_date, String] => {:class => Time, :nil => true, :accept_nil => true}
|
255
256
|
|
256
257
|
def get_date(signature)
|
257
|
-
if var = get_context_var('set_var', '
|
258
|
+
if var = get_context_var('set_var', 'main_date')
|
258
259
|
{:class => var.klass, :method => var, :nil => var.could_be_nil?}
|
259
260
|
else
|
260
261
|
{:class => Time, :method => 'main_date'}
|
@@ -279,7 +280,7 @@ EOL
|
|
279
280
|
end
|
280
281
|
|
281
282
|
# Select a date for the current context
|
282
|
-
def
|
283
|
+
def r_main_date
|
283
284
|
return nil unless code = get_attribute_or_eval
|
284
285
|
|
285
286
|
if format = @params[:format]
|
@@ -300,9 +301,9 @@ EOL
|
|
300
301
|
else
|
301
302
|
return parser_error("should evaluate to a String or Time (found #{code.klass})")
|
302
303
|
end
|
303
|
-
v = get_var_name('set_var', '
|
304
|
-
out "<% #{v} = #{code}
|
305
|
-
set_context_var('set_var', '
|
304
|
+
v = get_var_name('set_var', 'main_date')
|
305
|
+
out "<% #{v} = #{code} %>"
|
306
|
+
set_context_var('set_var', 'main_date', RubyLess::TypedString.new(v, :class => Time, :nil => could_be_nil))
|
306
307
|
out expand_with
|
307
308
|
end
|
308
309
|
|
data/lib/zena/use/display.rb
CHANGED
@@ -8,7 +8,7 @@ module Zena
|
|
8
8
|
else
|
9
9
|
finder = 'image'
|
10
10
|
end
|
11
|
-
"#{finder} group by id,l_id order by l_id desc, position asc
|
11
|
+
"#{finder} group by id,l_id order by l_id desc, position asc"
|
12
12
|
end
|
13
13
|
end # Common
|
14
14
|
|
@@ -466,9 +466,44 @@ module Zena
|
|
466
466
|
res = show_string(method)
|
467
467
|
end
|
468
468
|
|
469
|
-
res
|
469
|
+
res = extract_label(res, @params, @params[:attr])
|
470
|
+
|
471
|
+
if @params[:blank] == 'hide'
|
472
|
+
"<% if !#{method}.blank? %>#{@markup.wrap(res)}<% end %>"
|
473
|
+
else
|
474
|
+
res
|
475
|
+
end
|
470
476
|
end
|
471
477
|
|
478
|
+
def extract_label(res, params, attribute)
|
479
|
+
if (label = params[:label] || params[:tlabel]) && attribute
|
480
|
+
case label
|
481
|
+
when 'true'
|
482
|
+
"<label>#{attribute}</label> <span>#{res}</span>"
|
483
|
+
when 't'
|
484
|
+
"<label>#{trans(attribute)}</label> <span>#{res}</span>"
|
485
|
+
else
|
486
|
+
if params[:tlabel]
|
487
|
+
code = ::RubyLess.translate(self, "t(%Q{#{label}})")
|
488
|
+
else
|
489
|
+
code = ::RubyLess.translate_string(self, label)
|
490
|
+
end
|
491
|
+
if code.literal
|
492
|
+
"<label>#{code.literal}</label> <span>#{res}</span>"
|
493
|
+
else
|
494
|
+
"<label><%= #{code} %></label> <span>#{res}</span>"
|
495
|
+
end
|
496
|
+
end
|
497
|
+
else
|
498
|
+
res
|
499
|
+
end
|
500
|
+
end
|
501
|
+
|
502
|
+
# ??? <r:h do='foasfa'/> ?
|
503
|
+
# def r_h
|
504
|
+
# out "<%= h ??? %>"
|
505
|
+
# end
|
506
|
+
|
472
507
|
# Insert javascript asset tags
|
473
508
|
def r_javascripts
|
474
509
|
if @params[:list] == 'all' || @params[:list].nil?
|
@@ -493,16 +528,16 @@ module Zena
|
|
493
528
|
# Used by zafu templates that act as layouts (adminLayout for example) to insert the content if present
|
494
529
|
# or render.
|
495
530
|
def r_content_for_layout
|
496
|
-
"<% if content_for_layout = yield
|
531
|
+
"<% if content_for_layout = yield %><%= content_for_layout %><% else %>" +
|
497
532
|
expand_with +
|
498
|
-
"<% end
|
533
|
+
"<% end %>"
|
499
534
|
end
|
500
535
|
|
501
536
|
# Display the page's default title
|
502
537
|
def r_title_for_layout
|
503
|
-
"<% if @title_for_layout
|
538
|
+
"<% if @title_for_layout %><%= @title_for_layout %><% elsif @node && !@node.new_record? %><%= @node.title %><% elsif @node.parent %><%= @node.parent.short_path %><% else %>" +
|
504
539
|
expand_with +
|
505
|
-
"<% end
|
540
|
+
"<% end %>"
|
506
541
|
end
|
507
542
|
|
508
543
|
# Show html to add open a popup window to add a document.
|
@@ -512,7 +547,7 @@ module Zena
|
|
512
547
|
@markup.append_param(:class, 'btn_add')
|
513
548
|
node = self.node.list_context? ? self.node.up : self.node
|
514
549
|
res = node_action_link('add_doc', "<%= #{node}.zip %>", :text => text_for_link(''))
|
515
|
-
"<% if #{node}.can_write?
|
550
|
+
"<% if #{node}.can_write? %>#{wrap(res)}<% end %>"
|
516
551
|
end
|
517
552
|
|
518
553
|
# Find icon through a relation named 'icon' or use first image child
|
@@ -574,6 +609,18 @@ module Zena
|
|
574
609
|
end
|
575
610
|
end
|
576
611
|
|
612
|
+
def r_grid
|
613
|
+
return parser_error("not in a list context") unless node.list_context?
|
614
|
+
return parser_error("not a Node list") unless node.single_class <= Node
|
615
|
+
klass = "#{node.single_class.name}"
|
616
|
+
@blocks = [make(:void, :method => 'void', :text => %Q{<table class='grid'>
|
617
|
+
<tr do='#{klass}' do='roles'><th class='role' colspan='\#{columns.size}' do='each' do='name'/></tr>
|
618
|
+
<tr do='#{klass}' do='roles' do='each' do='columns'><th do='each' do='name'/></tr>
|
619
|
+
<tr do='each'><r:#{klass} do='roles' do='each' do='columns'><td do='each' do='@node.send(name)'/></r:#{klass}></tr>
|
620
|
+
</table>})]
|
621
|
+
expand_with
|
622
|
+
end
|
623
|
+
|
577
624
|
private
|
578
625
|
def show_number(method)
|
579
626
|
if fmt = @params[:format]
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Zena
|
2
|
+
module Use
|
3
|
+
module FieldIndex
|
4
|
+
module ModelMethods
|
5
|
+
def self.included(base)
|
6
|
+
# Declare all columns starting with idx_ as field index
|
7
|
+
::Column.add_field_index(base.column_names.select {|col| col =~ /\Aidx_/})
|
8
|
+
|
9
|
+
# base.alias_method_chain :property_field_index, :field_index
|
10
|
+
end
|
11
|
+
|
12
|
+
def property_field_index
|
13
|
+
if version.status == Zena::Status[:pub]
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end # ModelMethods
|
18
|
+
end # FieldIndex
|
19
|
+
end # Use
|
20
|
+
end # Zena
|
data/lib/zena/use/fixtures.rb
CHANGED
@@ -122,21 +122,24 @@ module Zena
|
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
125
|
-
define_method(table_name + "_id") do |
|
125
|
+
define_method(table_name + "_id") do |*fixtures|
|
126
126
|
raise Exception.new("$_test_site is blank!") if $_test_site.blank?
|
127
|
-
Zena::FoxyParser::id($_test_site,
|
127
|
+
res = fixtures.map {|f| Zena::FoxyParser::id($_test_site, f) }
|
128
|
+
fixtures.size > 1 ? res : res.first
|
128
129
|
end
|
129
130
|
end
|
130
131
|
|
131
132
|
if table_name == 'nodes' || table_name == 'zips'
|
132
|
-
define_method(table_name + "_zip") do |
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
133
|
+
define_method(table_name + "_zip") do |*fixtures|
|
134
|
+
res = fixtures.map do |fixture|
|
135
|
+
fixture_name = table_name == 'zips' ? fixture.to_s : "#{$_test_site}_#{fixture}"
|
136
|
+
if fix = @@loaded_fixtures[table_name][fixture_name]
|
137
|
+
fix.instance_eval { @fixture['zip'].to_i }
|
138
|
+
else
|
139
|
+
raise StandardError, "No fixture with name '#{fixture_name}' found for table '#{table_name}'"
|
140
|
+
end
|
139
141
|
end
|
142
|
+
fixtures.size > 1 ? res : res.first
|
140
143
|
end
|
141
144
|
end
|
142
145
|
|
data/lib/zena/use/forms.rb
CHANGED
@@ -9,39 +9,71 @@ module Zena
|
|
9
9
|
klass.new_instance(Node.transform_attributes(params))
|
10
10
|
end
|
11
11
|
|
12
|
-
def make_checkbox(node,
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
12
|
+
def make_checkbox(node, opts)
|
13
|
+
if relation_name = opts[:role]
|
14
|
+
values, attribute = opts[:list], opts[:attr]
|
15
|
+
relation_proxy = node.relation_proxy(relation_name)
|
16
|
+
return nil unless values && relation_proxy
|
17
|
+
|
18
|
+
res = []
|
19
|
+
role = relation_proxy.other_role
|
20
|
+
|
21
|
+
if relation_proxy.unique?
|
22
|
+
current_value = relation_proxy.other_id
|
23
|
+
values.each do |value|
|
24
|
+
res << ("<input type='radio' name='node[#{role}_id]' value='#{value.zip}'" +
|
25
|
+
(current_value == value.id ? " checked='checked'/> " : '/> ') +
|
26
|
+
"<span>#{value.prop[attribute]}</span>")
|
27
|
+
end
|
28
|
+
res << "<input type='radio' name='node[#{role}_id]' value=''/> <span>#{_('none')}</span>"
|
29
|
+
else
|
30
|
+
current_values = relation_proxy.other_ids
|
31
|
+
res << "<input type='hidden' name='node[#{role}_ids][]' value=''/>"
|
32
|
+
values.each do |value|
|
33
|
+
res << ("<span><input type='checkbox' name='node[#{role}_ids][]' value='#{value.zip}'" +
|
34
|
+
(current_values.include?(value.id) ? " checked='checked'/> " : '/> ') +
|
35
|
+
"<span>#{value.prop[attribute]}</span>")
|
36
|
+
end
|
28
37
|
end
|
29
|
-
res
|
30
|
-
|
31
|
-
res << "<span><input type='radio' name='node[#{role}_id]' value=''/> #{_('none')}</span>"
|
38
|
+
res.join('')
|
32
39
|
else
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
+
# literal values
|
41
|
+
list, name, selected = opts[:list], opts[:name], opts[:selected]
|
42
|
+
show = opts[:show] || list
|
43
|
+
if selected.kind_of?(Array)
|
44
|
+
selected = selected.map(&:to_s)
|
45
|
+
name = "node[#{name}][]"
|
46
|
+
else
|
47
|
+
selected = [selected.to_s]
|
48
|
+
name = "node[#{name}]"
|
49
|
+
end
|
50
|
+
res = []
|
51
|
+
res << "<input type='hidden' name='#{name}' value=''/>"
|
52
|
+
list.each_with_index do |value, i|
|
53
|
+
res << ("<input type='checkbox' name='#{name}' value='#{value}'" +
|
54
|
+
(selected.include?(value.to_s) ? " checked='checked'/> " : '/> ') +
|
55
|
+
"<span>#{show[i]}</span>")
|
56
|
+
end
|
57
|
+
res.join('')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Find a params value from an input name (q[foo] ==> safe params[q][foo])
|
62
|
+
def param_value(name)
|
63
|
+
# q[foo.bar][xxx]
|
64
|
+
list = name.gsub(']','').split('[')
|
65
|
+
# q foo.bar xxx
|
66
|
+
base = params
|
67
|
+
while true
|
68
|
+
key = list.shift
|
69
|
+
if base.kind_of?(Hash)
|
70
|
+
base = base[key]
|
71
|
+
else
|
72
|
+
return nil
|
40
73
|
end
|
41
|
-
|
42
|
-
res << "<input type='hidden' name='node[#{role}_ids][]' value=''/>"
|
74
|
+
break if list.empty?
|
43
75
|
end
|
44
|
-
|
76
|
+
base
|
45
77
|
end
|
46
78
|
end # ViewMethods
|
47
79
|
|
@@ -61,7 +93,12 @@ module Zena
|
|
61
93
|
next unless type = klass.safe_method_type([key.to_s])
|
62
94
|
# Store how to access current value to show hidden field in form.
|
63
95
|
keys[key] = type[:method]
|
64
|
-
|
96
|
+
code = RubyLess.translate(self, value)
|
97
|
+
if code.klass == type[:class]
|
98
|
+
res << ":#{key} => #{code}"
|
99
|
+
else
|
100
|
+
out parser_error("invalid type for '#{key}' (found #{code.klass}, expected #{type[:class]})")
|
101
|
+
end
|
65
102
|
end
|
66
103
|
|
67
104
|
if res == []
|
@@ -71,10 +108,11 @@ module Zena
|
|
71
108
|
end
|
72
109
|
|
73
110
|
expand_with_finder(
|
74
|
-
:method
|
75
|
-
:class
|
76
|
-
:nil
|
77
|
-
:
|
111
|
+
:method => method,
|
112
|
+
:class => klass,
|
113
|
+
:nil => true,
|
114
|
+
:new_record => true,
|
115
|
+
:new_keys => keys
|
78
116
|
)
|
79
117
|
end
|
80
118
|
|
@@ -110,7 +148,7 @@ module Zena
|
|
110
148
|
if name
|
111
149
|
type ||= node.klass.safe_method_type([name])
|
112
150
|
# do we have a property ?
|
113
|
-
if type && (node.
|
151
|
+
if type && (node.real_class.column_names.include?(name) || node.klass.column_names.include?(name))
|
114
152
|
# create an input field
|
115
153
|
out make_input(form_helper, name, type[:class], textarea)
|
116
154
|
else
|
@@ -144,6 +182,12 @@ module Zena
|
|
144
182
|
dom_name = node.dom_prefix
|
145
183
|
opts[:form_helper] = 'f'
|
146
184
|
|
185
|
+
if upd = @params[:update]
|
186
|
+
if target = find_target(upd)
|
187
|
+
@context[:template_url] = target.template_url
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
147
191
|
if template_url = @context[:template_url]
|
148
192
|
# Ajax
|
149
193
|
|
@@ -161,11 +205,11 @@ module Zena
|
|
161
205
|
}
|
162
206
|
|
163
207
|
opts[:form_cancel] = %Q{
|
164
|
-
<% if #{node}.new_record?
|
208
|
+
<% if #{node}.new_record? %>
|
165
209
|
<p class='btn_x'><a href='#' onclick='[\"<%= params[:dom_id] %>_add\", \"<%= params[:dom_id] %>_form\"].each(Element.toggle);return false;'>#{_('btn_x')}</a></p>
|
166
|
-
<% else
|
210
|
+
<% else %>
|
167
211
|
<p class='btn_x'><%= link_to_remote(#{_('btn_x').inspect}, :url => #{node.form_name}_path(#{node}.zip) + \"/zafu?t_url=#{CGI.escape(template_url)}&dom_id=\#{params[:dom_id]}#{@context[:has_link_id] ? "&link_id=\#{#{node}.link_id}" : ''}\", :method => :get) %></p>
|
168
|
-
<% end
|
212
|
+
<% end %>
|
169
213
|
}
|
170
214
|
end
|
171
215
|
else
|
@@ -194,7 +238,7 @@ module Zena
|
|
194
238
|
set_fields << "#{node.form_name}[#{tag.params[:name]}]"
|
195
239
|
end
|
196
240
|
|
197
|
-
if template_url = @context[:template_url]
|
241
|
+
if template_url = @context[:template_url]
|
198
242
|
# Ajax
|
199
243
|
|
200
244
|
if (descendants('input') || []).detect {|elem| elem.params[:type] == 'submit'}
|
@@ -206,21 +250,23 @@ module Zena
|
|
206
250
|
|
207
251
|
hidden_fields['link_id'] = "<%= #{node}.link_id %>" if @context[:has_link_id] && node.will_be?(Node)
|
208
252
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
253
|
+
if upd = @params[:update]
|
254
|
+
if target = find_target(upd)
|
255
|
+
hidden_fields['u_url'] = target.template_url
|
256
|
+
hidden_fields['udom_id'] = upd # target.node.dom_prefix ? (but target.node is not set yet...)
|
257
|
+
# hidden_fields['u_id'] = "<%= #{@context[:parent_node]}.zip %>" if @context[:in_add]
|
258
|
+
hidden_fields['s'] = "<%= start_node_zip %>"
|
259
|
+
end
|
216
260
|
# elsif (block = ancestor('block')) && node.will_be?(DataEntry)
|
217
261
|
# # updates template url
|
218
262
|
# hidden_fields['u_url'] = block.template_url
|
219
263
|
# hidden_fields['udom_id'] = block.erb_dom_id
|
220
|
-
|
264
|
+
end
|
221
265
|
|
222
266
|
hidden_fields['t_url'] = template_url
|
223
267
|
|
268
|
+
|
269
|
+
# t_id = node zip to use when rendering partial (enable back when we have a use case).
|
224
270
|
# if t_id = @params[:t_id]
|
225
271
|
# hidden_fields['t_id'] = parse_attributes_in_value(t_id)
|
226
272
|
# end
|
@@ -235,7 +281,9 @@ module Zena
|
|
235
281
|
# 1. @node
|
236
282
|
# 2. var1 = @node.children
|
237
283
|
# 3. var1_new = Node.new
|
238
|
-
|
284
|
+
if node.opts[:new_record]
|
285
|
+
hidden_fields['node[parent_id]'] = "<%= #{@context[:in_add] ? "#{node.up.up}.zip" : "#{node}.parent_zip"} %>"
|
286
|
+
end
|
239
287
|
elsif node.will_be?(Comment)
|
240
288
|
# FIXME: the "... || '@node'" is a hack and I don't understand why it's needed...
|
241
289
|
hidden_fields['node_id'] = "<%= #{node.up || '@node'}.zip %>"
|
@@ -276,7 +324,16 @@ module Zena
|
|
276
324
|
end
|
277
325
|
else
|
278
326
|
# no ajax
|
279
|
-
|
327
|
+
|
328
|
+
if node.will_be?(Node)
|
329
|
+
# Nested contexts:
|
330
|
+
# 1. @node
|
331
|
+
# 2. var1 = @node.children
|
332
|
+
# 3. var1_new = Node.new
|
333
|
+
if node.opts[:new_record]
|
334
|
+
hidden_fields['node[parent_id]'] = "<%= #{node.up}.zip %>"
|
335
|
+
end
|
336
|
+
end
|
280
337
|
cancel = "" # link to normal node ?
|
281
338
|
end
|
282
339
|
|
@@ -321,39 +378,49 @@ module Zena
|
|
321
378
|
end
|
322
379
|
|
323
380
|
def r_textarea
|
324
|
-
|
381
|
+
params = @markup.params.merge(@params)
|
382
|
+
res = make_textarea(params)
|
383
|
+
extract_label(res, params, params[:name])
|
325
384
|
end
|
326
385
|
|
327
386
|
# <r:select name='klass' root_class='...'/>
|
328
|
-
# <r:select name='parent_id'
|
387
|
+
# <r:select name='parent_id' nodes='projects in site'/>
|
388
|
+
# <r:select name='parent_id' values='a,b,c'/>
|
329
389
|
# TODO: optimization (avoid loading full AR to only use [id, name])
|
330
390
|
def r_select
|
331
391
|
html_attributes, attribute = get_input_params()
|
332
|
-
return
|
333
|
-
|
334
|
-
if
|
335
|
-
selected
|
336
|
-
|
337
|
-
selected = "params[#{attribute.to_sym.inspect}].to_s"
|
338
|
-
elsif %w{parent_id}.include?(attribute)
|
339
|
-
selected = "#{node}.parent_zip.to_s"
|
340
|
-
elsif attribute == 'copy_id'
|
341
|
-
selected = 'nil'
|
342
|
-
elsif attribute =~ /^(.*)_id$/
|
343
|
-
# relation
|
344
|
-
selected = "#{node}.rel[#{$1.inspect}].other_zip.to_s"
|
392
|
+
# TEMPORARY HACK UNTIL WE FIX get_input_params to return a single hash with
|
393
|
+
# {:html => { prepared html attributes }, :raw => {:value => '..', :name => '..', :param => '..'}}
|
394
|
+
if param = @params[:param]
|
395
|
+
selected = "params[#{param.to_sym.inspect}].to_s"
|
396
|
+
attribute = param
|
345
397
|
else
|
346
|
-
|
398
|
+
return parser_error("missing name") unless attribute
|
399
|
+
|
400
|
+
if value = @params[:selected]
|
401
|
+
selected = ::RubyLess.translate_string(self, value)
|
402
|
+
elsif @context[:in_filter]
|
403
|
+
selected = "params[#{attribute.to_sym.inspect}].to_s"
|
404
|
+
elsif %w{parent_id}.include?(attribute)
|
405
|
+
selected = "#{node}.parent_zip.to_s"
|
406
|
+
elsif attribute == 'copy_id'
|
407
|
+
selected = 'nil'
|
408
|
+
elsif attribute =~ /^(.*)_id$/
|
409
|
+
# relation
|
410
|
+
selected = "#{node}.rel[#{$1.inspect}].other_zip.to_s"
|
411
|
+
else
|
412
|
+
selected = "#{node}.prop[#{attribute.inspect}].to_s"
|
413
|
+
end
|
347
414
|
end
|
348
415
|
|
349
416
|
html_id = html_attributes[:id] ? " id='#{html_attributes[:id]}'" : ''
|
350
|
-
if @context[:in_filter]
|
417
|
+
if @context[:in_filter] || @params[:param]
|
351
418
|
select_tag = "<select#{html_id} name='#{attribute}'>"
|
352
419
|
else
|
353
420
|
select_tag = "<select#{html_id} name='#{node.form_name}[#{attribute}]'>"
|
354
421
|
end
|
355
422
|
|
356
|
-
if klass = @params[:root_class]
|
423
|
+
res = if klass = @params[:root_class]
|
357
424
|
class_opts = ''
|
358
425
|
class_opts << ", :without => #{@params[:without].inspect}" if @params[:without]
|
359
426
|
# do not use 'selected' if the node is not new
|
@@ -366,19 +433,28 @@ module Zena
|
|
366
433
|
else
|
367
434
|
parser_error("missing 'nodes', 'root_class' or 'values'")
|
368
435
|
end
|
436
|
+
|
437
|
+
extract_label(res, @params, attribute)
|
369
438
|
end
|
370
439
|
|
371
440
|
|
372
441
|
def r_input
|
373
442
|
html_attributes, attribute = get_input_params()
|
374
|
-
|
443
|
+
# TODO: get attribute type from get_input_params
|
444
|
+
res = case @params[:type]
|
375
445
|
when 'select' # FIXME: why is this only for classes ?
|
376
446
|
out parser_error("please use [select] here")
|
377
447
|
r_select
|
378
448
|
when 'date_box', 'date'
|
379
449
|
return parser_error("date_box without name") unless attribute
|
380
|
-
|
381
|
-
|
450
|
+
code = ::RubyLess.translate(self, "this.#{attribute}")
|
451
|
+
value = @context[:in_add] ? "''" : code
|
452
|
+
html_params = [':size => 15']
|
453
|
+
[:style, :class, :onclick, :size].each do |key|
|
454
|
+
html_params << ":#{key} => #{@params[key].inspect}" if @params[key]
|
455
|
+
end
|
456
|
+
html_params << ":id=>\"#{dom_id}_#{attribute}\"" if @context[:dom_prefix]
|
457
|
+
"<%= date_box(#{node}, #{attribute.inspect}, :value => #{value}, #{html_params.join(', ')}) %>"
|
382
458
|
when 'id'
|
383
459
|
return parser_error("select id without name") unless attribute
|
384
460
|
name = "#{attribute}_id" unless attribute[-3..-1] == '_id'
|
@@ -395,6 +471,7 @@ module Zena
|
|
395
471
|
wrap('')
|
396
472
|
else
|
397
473
|
# 'text', 'hidden', ...
|
474
|
+
return parser_error('Missing name.') unless attribute || html_attributes[:name]
|
398
475
|
@markup.tag = 'input'
|
399
476
|
@markup.set_param(:type, @params[:type] || 'text')
|
400
477
|
|
@@ -404,30 +481,57 @@ module Zena
|
|
404
481
|
@markup.append_attribute checked if checked
|
405
482
|
wrap('')
|
406
483
|
end
|
484
|
+
|
485
|
+
extract_label(res, @params, attribute || html_attributes[:name])
|
407
486
|
end
|
408
487
|
|
409
488
|
# <r:checkbox role='collaborator_for' values='projects' in='site'/>"
|
410
489
|
def r_checkbox
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
490
|
+
nodes = @params[:nodes]
|
491
|
+
values = @params[:values]
|
492
|
+
return parser_error("missing 'nodes' or 'values'") unless nodes || values
|
493
|
+
|
494
|
+
if values
|
495
|
+
return parser_error("missing attribute 'name'") unless name = @params[:name]
|
496
|
+
# parse literal values
|
497
|
+
opts = [":name => #{name.inspect}", ":list => #{values.split(',').map(&:strip).inspect}"]
|
498
|
+
if show_values = @params[:show]
|
499
|
+
opts << ":show => #{show_values.split(',').map(&:strip).inspect}"
|
500
|
+
elsif show_values = @params[:tshow]
|
501
|
+
opts << ":show => #{translate_list(show_values).inspect}"
|
502
|
+
end
|
503
|
+
meth = RubyLess.translate(self, "this.#{name}")
|
504
|
+
opts << ":selected => #{meth}"
|
505
|
+
attribute = name
|
506
|
+
res = "<%= make_checkbox(#{node}, #{opts.join(', ')}) %>"
|
424
507
|
else
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
508
|
+
if name = @params[:name]
|
509
|
+
if name =~ /(.*)_ids?\Z/
|
510
|
+
role = $1
|
511
|
+
else
|
512
|
+
role = name
|
513
|
+
end
|
514
|
+
else
|
515
|
+
role = @params[:role]
|
516
|
+
end
|
517
|
+
return parser_error("missing 'role'") unless role
|
518
|
+
# nodes
|
519
|
+
meth = role.singularize
|
520
|
+
|
521
|
+
if nodes =~ /^\d+\s*($|,)/
|
522
|
+
values = nodes.split(',').map{|v| v.to_i}
|
523
|
+
finder = "secure(Node) { Node.all(:conditions => 'zip IN (#{values.join(',')})') }"
|
524
|
+
else
|
525
|
+
return unless finder = build_finder(:all, nodes, @params)
|
526
|
+
return parser_error("invalid class (#{finder[:class]})") unless finder[:class].first <= Node
|
527
|
+
finder = finder[:method]
|
528
|
+
end
|
529
|
+
|
530
|
+
attribute = @params[:attr] || 'title'
|
531
|
+
res = "<%= make_checkbox(#{node}, :list => #{finder}, :role => #{meth.inspect}, :attr => #{attribute.inspect}) %>"
|
429
532
|
end
|
430
|
-
|
533
|
+
|
534
|
+
extract_label(res, @params, attribute)
|
431
535
|
end
|
432
536
|
|
433
537
|
alias r_radio r_checkbox
|
@@ -449,23 +553,27 @@ module Zena
|
|
449
553
|
|
450
554
|
# Parse params to extract everything that is relevant to building input fields.
|
451
555
|
# TODO: refactor and pass the @markup so that attributes are added directly
|
556
|
+
# TODO: get attribute type in get_input_params (safe_method_type)
|
452
557
|
def get_input_params(params = @params)
|
453
558
|
res = Zafu::OrderedHash.new
|
454
|
-
if name = (params[:name] || params[:date])
|
559
|
+
if name = (params[:param] || params[:name] || params[:date])
|
455
560
|
res[:name] = name
|
456
|
-
|
457
|
-
#
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
end
|
463
|
-
|
464
|
-
unless @context[:in_filter] || attribute == 's'
|
465
|
-
if sub_attr
|
466
|
-
res[:name] = "#{node.form_name}[#{attribute}][#{sub_attr}]"
|
561
|
+
unless params[:param]
|
562
|
+
# build name
|
563
|
+
if res[:name] =~ /\A([\w_]+)\[(.*?)\]/
|
564
|
+
# Sub attributes are used with tags or might be used for other features. It
|
565
|
+
# enables things like 'tagged[foo]'
|
566
|
+
attribute, sub_attr = $1, $2
|
467
567
|
else
|
468
|
-
|
568
|
+
attribute = res[:name]
|
569
|
+
end
|
570
|
+
|
571
|
+
unless @context[:in_filter] || attribute == 's'
|
572
|
+
if sub_attr
|
573
|
+
res[:name] = "#{node.form_name}[#{attribute}][#{sub_attr}]"
|
574
|
+
else
|
575
|
+
res[:name] = "#{node.form_name}[#{attribute}]"
|
576
|
+
end
|
469
577
|
end
|
470
578
|
end
|
471
579
|
|
@@ -480,11 +588,17 @@ module Zena
|
|
480
588
|
value = RubyLess.translate_string(self, value)
|
481
589
|
|
482
590
|
if value.literal
|
483
|
-
res[:value] = value.literal.to_s
|
591
|
+
res[:value] = form_quote(value.literal.to_s)
|
484
592
|
else
|
485
593
|
res[:value] = "<%= fquote #{value} %>"
|
486
594
|
end
|
487
|
-
elsif
|
595
|
+
elsif params[:param]
|
596
|
+
if name =~ /^[a-z_]+$/
|
597
|
+
res[:value] = "<%= fquote params[:#{name}] %>"
|
598
|
+
else
|
599
|
+
res[:value] = "<%= fquote param_value(#{name.inspect}) %>"
|
600
|
+
end
|
601
|
+
elsif attribute && type = node.klass.safe_method_type([attribute])
|
488
602
|
res[:value] = "<%= fquote #{node}.#{type[:method]} %>"
|
489
603
|
end
|
490
604
|
end
|
@@ -605,9 +719,7 @@ module Zena
|
|
605
719
|
if show = @params[:show]
|
606
720
|
show_values = show.split(',').map(&:strip)
|
607
721
|
elsif show = @params[:tshow]
|
608
|
-
show_values = show
|
609
|
-
_(s.strip)
|
610
|
-
end
|
722
|
+
show_values = translate_list(show)
|
611
723
|
end
|
612
724
|
|
613
725
|
if show_values
|
@@ -616,6 +728,18 @@ module Zena
|
|
616
728
|
end
|
617
729
|
end
|
618
730
|
options_list.inspect
|
731
|
+
elsif code = @params[:eval]
|
732
|
+
ruby = ::RubyLess.translate(self, code)
|
733
|
+
if !ruby.klass.kind_of?(Array)
|
734
|
+
return parser_error("invalid eval: should return an Array (found #{ruby.klass})")
|
735
|
+
end
|
736
|
+
|
737
|
+
if ruby.klass.first <= String
|
738
|
+
# ok
|
739
|
+
ruby
|
740
|
+
else
|
741
|
+
return parser_error("cannot extract values from eval (not a String list: [#{ruby.klass.first}])")
|
742
|
+
end
|
619
743
|
end
|
620
744
|
end
|
621
745
|
|