hobo 1.1.0 → 1.3.0.RC
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +238 -287
- data/Rakefile +14 -31
- data/VERSION +1 -0
- data/{lib/hobo → app/controllers}/dev_controller.rb +6 -6
- data/app/controllers/dryml_support_controller.rb +13 -0
- data/{rails_generators/hobo_front_controller/templates → app/views/dev}/summary.dryml +7 -10
- data/bin/hobo +12 -144
- data/config/initializers/inflections.rb +3 -0
- data/config/routes.rb +6 -0
- data/{doctest → doctests}/hobo/lifecycles.rdoctest +40 -59
- data/{doctest → doctests/hobo}/model.rdoctest +33 -40
- data/{doctest → doctests/hobo}/multi_model_forms.rdoctest +15 -19
- data/{doctest → doctests/hobo}/scopes.rdoctest +27 -41
- data/doctests/prepare_testapp.rb +8 -0
- data/hobo.gemspec +26 -199
- data/lib/generators/hobo/activation_email.rb +11 -0
- data/lib/generators/hobo/admin_subsite/admin_subsite_generator.rb +35 -0
- data/lib/generators/hobo/admin_subsite/templates/admin.css +20 -0
- data/lib/generators/hobo/admin_subsite/templates/admin_tag_injection.erb +10 -0
- data/{rails_generators/hobo_admin_site → lib/generators/hobo/admin_subsite}/templates/application.dryml +0 -0
- data/{rails_generators/hobo_admin_site/templates/controller.rb → lib/generators/hobo/admin_subsite/templates/controller.rb.erb} +5 -5
- data/lib/generators/hobo/admin_subsite/templates/users_index.dryml +7 -0
- data/lib/generators/hobo/assets/assets_generator.rb +18 -0
- data/{rails_generators/hobo → lib/generators/hobo/assets}/templates/application.css +0 -0
- data/lib/generators/hobo/assets/templates/application.dryml.erb +9 -0
- data/{rails_generators/hobo → lib/generators/hobo/assets}/templates/dryml-support.js +2 -2
- data/lib/generators/hobo/assets/templates/dryml_taglibs_initializer.rb +1 -0
- data/lib/generators/hobo/assets/templates/en_injection.yml +19 -0
- data/{rails_generators/hobo → lib/generators/hobo/assets}/templates/guest.rb +1 -1
- data/lib/generators/hobo/controller.rb +35 -0
- data/lib/generators/hobo/controller/controller_generator.rb +6 -0
- data/lib/generators/hobo/controller/templates/controller.rb.erb +7 -0
- data/{rails_generators/hobo_front_controller → lib/generators/hobo/front_controller}/USAGE +0 -0
- data/lib/generators/hobo/front_controller/front_controller_generator.rb +55 -0
- data/{rails_generators/hobo_front_controller/templates/controller.rb → lib/generators/hobo/front_controller/templates/controller.rb.erb} +0 -0
- data/{rails_generators/hobo_front_controller → lib/generators/hobo/front_controller}/templates/index.dryml +6 -12
- data/lib/generators/hobo/i18n/i18n_generator.rb +35 -0
- data/lib/generators/hobo/i18n/templates/app.de.yml +30 -0
- data/lib/generators/hobo/i18n/templates/app.en.yml +25 -0
- data/lib/generators/hobo/i18n/templates/app.es.yml +31 -0
- data/lib/generators/hobo/i18n/templates/app.fr.yml +26 -0
- data/lib/generators/hobo/i18n/templates/app.it.yml +28 -0
- data/lib/generators/hobo/i18n/templates/app.pt-PT.yml +25 -0
- data/lib/generators/hobo/i18n/templates/app.ru.yml +24 -0
- data/lib/generators/hobo/i18n/templates/hobo.de.yml +204 -0
- data/lib/generators/hobo/i18n/templates/hobo.en.yml +195 -0
- data/lib/generators/hobo/i18n/templates/hobo.es.yml +202 -0
- data/lib/generators/hobo/i18n/templates/hobo.fr.yml +195 -0
- data/lib/generators/hobo/i18n/templates/hobo.it.yml +202 -0
- data/lib/generators/hobo/i18n/templates/hobo.pt-PT.yml +196 -0
- data/lib/generators/hobo/i18n/templates/hobo.ru.yml +200 -0
- data/lib/generators/hobo/invite_only.rb +18 -0
- data/lib/generators/hobo/model/USAGE +19 -0
- data/lib/generators/hobo/model/model_generator.rb +11 -0
- data/{rails_generators/hobo_model/templates/model.rb → lib/generators/hobo/model/templates/model_injection.rb.erb} +0 -2
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/USAGE +0 -0
- data/lib/generators/hobo/rapid/rapid_generator.rb +24 -0
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/IE7.js +0 -0
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/blank.gif +0 -0
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/hobo-rapid.css +0 -0
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/hobo-rapid.js +65 -65
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/ie7-recalc.js +21 -21
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/lowpro.js +31 -31
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/reset.css +1 -1
- data/lib/generators/hobo/rapid/templates/themes/clean-sidemenu/public/images/100-ACD3E6-DBE1E5-H.png +0 -0
- data/lib/generators/hobo/rapid/templates/themes/clean-sidemenu/public/images/100-DBE1E5-FCFEF5-H.png +0 -0
- data/lib/generators/hobo/rapid/templates/themes/clean-sidemenu/public/images/300-3B5F87-ACD3E6-H.png +0 -0
- data/{rails_generators/hobo_rapid/templates/themes/clean → lib/generators/hobo/rapid/templates/themes/clean-sidemenu}/public/images/spinner.gif +0 -0
- data/lib/generators/hobo/rapid/templates/themes/clean-sidemenu/public/stylesheets/clean-sidemenu.css +81 -0
- data/lib/generators/hobo/rapid/templates/themes/clean-sidemenu/views/clean-sidemenu.dryml +30 -0
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/themes/clean/public/images/101-3B5F87-ACD3E6.png +0 -0
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/themes/clean/public/images/30-3E547A-242E42.png +0 -0
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/themes/clean/public/images/30-DBE1E5-FCFEF5.png +0 -0
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/themes/clean/public/images/300-ACD3E6-fff.png +0 -0
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/themes/clean/public/images/50-ACD3E6-fff.png +0 -0
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/themes/clean/public/images/fieldbg.gif +0 -0
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/themes/clean/public/images/pencil.png +0 -0
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/themes/clean/public/images/small_close.png +0 -0
- data/lib/generators/hobo/rapid/templates/themes/clean/public/images/spinner.gif +0 -0
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/themes/clean/public/stylesheets/clean.css +16 -16
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/themes/clean/public/stylesheets/rapid-ui.css +3 -3
- data/{rails_generators/hobo_rapid → lib/generators/hobo/rapid}/templates/themes/clean/views/clean.dryml +1 -1
- data/lib/generators/hobo/resource/resource_generator.rb +23 -0
- data/lib/generators/hobo/routes/USAGE +9 -0
- data/lib/generators/hobo/routes/router.rb +115 -0
- data/lib/generators/hobo/routes/routes_generator.rb +40 -0
- data/lib/generators/hobo/routes/templates/hobo_routes.rb.erb +33 -0
- data/lib/generators/hobo/setup_wizard/USAGE +4 -0
- data/lib/generators/hobo/setup_wizard/setup_wizard_generator.rb +274 -0
- data/lib/generators/hobo/subsite.rb +48 -0
- data/lib/generators/hobo/subsite/subsite_generator.rb +16 -0
- data/{rails_generators/hobo_subsite → lib/generators/hobo/subsite}/templates/application.dryml +0 -0
- data/{rails_generators/hobo_subsite/templates/controller.rb → lib/generators/hobo/subsite/templates/controller.rb.erb} +1 -1
- data/lib/generators/hobo/subsite_taglib/subsite_taglib_generator.rb +16 -0
- data/{rails_generators/hobo_admin_site/templates/site_taglib.dryml → lib/generators/hobo/subsite_taglib/templates/taglib.dryml.erb} +9 -10
- data/lib/generators/hobo/taglib.rb +12 -0
- data/lib/generators/hobo/test_framework/test_framework_generator.rb +72 -0
- data/lib/generators/hobo/test_options.rb +19 -0
- data/{rails_generators/hobo_user_controller → lib/generators/hobo/user_controller}/templates/accept_invitation.dryml +0 -0
- data/lib/generators/hobo/user_controller/templates/controller.rb.erb +31 -0
- data/lib/generators/hobo/user_controller/user_controller_generator.rb +25 -0
- data/lib/generators/hobo/user_mailer/templates/activation.erb +9 -0
- data/{rails_generators/hobo_user_model → lib/generators/hobo/user_mailer}/templates/forgot_password.erb +2 -2
- data/{rails_generators/hobo_user_model → lib/generators/hobo/user_mailer}/templates/invite.erb +2 -2
- data/lib/generators/hobo/user_mailer/templates/mailer.rb.erb +25 -0
- data/lib/generators/hobo/user_mailer/user_mailer_generator.rb +33 -0
- data/lib/generators/hobo/user_model/USAGE +12 -0
- data/{rails_generators/hobo_user_model/templates/model.rb → lib/generators/hobo/user_model/templates/model_injection.rb.erb} +40 -20
- data/lib/generators/hobo/user_model/user_model_generator.rb +23 -0
- data/lib/generators/hobo/user_resource/user_resource_generator.rb +27 -0
- data/lib/hobo.rb +29 -129
- data/lib/hobo/controller.rb +37 -47
- data/lib/hobo/controller/authentication_support.rb +109 -0
- data/lib/hobo/{model_controller.rb → controller/model.rb} +71 -79
- data/lib/hobo/{user_controller.rb → controller/user.rb} +59 -49
- data/lib/hobo/engine.rb +80 -0
- data/lib/hobo/extensions/action_controller/hobo_methods.rb +44 -0
- data/lib/hobo/extensions/action_mailer/helper.rb +38 -0
- data/lib/{action_view_extensions/helpers → hobo/extensions/action_view}/tag_helper.rb +5 -2
- data/lib/hobo/extensions/action_view/translation_helper.rb +25 -0
- data/lib/hobo/extensions/active_model/name.rb +16 -0
- data/lib/hobo/extensions/active_model/translation.rb +35 -0
- data/lib/{active_record/association_collection.rb → hobo/extensions/active_record/associations/collection.rb} +8 -17
- data/lib/{active_record/association_proxy.rb → hobo/extensions/active_record/associations/proxy.rb} +6 -7
- data/lib/hobo/extensions/active_record/associations/reflection.rb +23 -0
- data/lib/hobo/extensions/active_record/associations/scope.rb +35 -0
- data/lib/hobo/extensions/active_record/hobo_methods.rb +11 -0
- data/lib/hobo/extensions/active_record/permissions.rb +159 -0
- data/lib/hobo/extensions/active_record/relation_with_origin.rb +28 -0
- data/lib/hobo/extensions/array.rb +27 -0
- data/lib/hobo/extensions/enumerable.rb +12 -0
- data/lib/hobo/extensions/i18n.rb +17 -0
- data/lib/hobo/{hobo_helper.rb → helper.rb} +58 -31
- data/lib/hobo/helper/translations.rb +54 -0
- data/lib/hobo/helper/translations/normalizer.rb +39 -0
- data/lib/hobo/model.rb +61 -95
- data/lib/hobo/model/accessible_associations.rb +178 -0
- data/lib/hobo/{find_for.rb → model/find_for.rb} +17 -17
- data/lib/hobo/model/guest.rb +25 -0
- data/lib/hobo/model/include_in_save.rb +55 -0
- data/lib/hobo/model/lifecycles.rb +119 -0
- data/lib/hobo/model/lifecycles/actions.rb +146 -0
- data/lib/hobo/model/lifecycles/creator.rb +74 -0
- data/lib/hobo/model/lifecycles/lifecycle.rb +243 -0
- data/lib/hobo/model/lifecycles/state.rb +22 -0
- data/lib/hobo/model/lifecycles/transition.rb +70 -0
- data/lib/hobo/model/permissions.rb +448 -0
- data/lib/hobo/model/scopes.rb +38 -0
- data/lib/hobo/model/scopes/apply_scopes.rb +21 -0
- data/lib/hobo/model/scopes/automatic_scopes.rb +428 -0
- data/lib/hobo/model/user_base.rb +184 -0
- data/lib/hobo/model/view_hints.rb +123 -0
- data/{rapid_generators → lib/hobo/rapid/generators}/rapid/cards.dryml.erb +2 -2
- data/{rapid_generators → lib/hobo/rapid/generators}/rapid/forms.dryml.erb +3 -3
- data/{rapid_generators → lib/hobo/rapid/generators}/rapid/pages.dryml.erb +38 -51
- data/lib/hobo/rapid/helper.rb +166 -0
- data/{taglibs → lib/hobo/rapid/taglibs}/rapid.dryml +6 -5
- data/{taglibs → lib/hobo/rapid/taglibs}/rapid_core.dryml +286 -118
- data/{taglibs → lib/hobo/rapid/taglibs}/rapid_document_tags.dryml +2 -2
- data/{taglibs → lib/hobo/rapid/taglibs}/rapid_editing.dryml +45 -45
- data/{taglibs → lib/hobo/rapid/taglibs}/rapid_forms.dryml +190 -158
- data/{taglibs → lib/hobo/rapid/taglibs}/rapid_generics.dryml +12 -9
- data/lib/hobo/rapid/taglibs/rapid_i18n.dryml +107 -0
- data/{taglibs → lib/hobo/rapid/taglibs}/rapid_lifecycles.dryml +7 -7
- data/{taglibs → lib/hobo/rapid/taglibs}/rapid_navigation.dryml +15 -15
- data/{taglibs → lib/hobo/rapid/taglibs}/rapid_pages.dryml +37 -36
- data/{taglibs → lib/hobo/rapid/taglibs}/rapid_plus.dryml +107 -43
- data/{taglibs → lib/hobo/rapid/taglibs}/rapid_summary.dryml +28 -57
- data/{taglibs → lib/hobo/rapid/taglibs}/rapid_support.dryml +9 -9
- data/{taglibs → lib/hobo/rapid/taglibs}/rapid_user_pages.dryml +41 -40
- data/lib/hobo/routes.rb +31 -0
- data/{doctest → test/doctest}/hobo/hobo_helper.rdoctest +11 -11
- data/test/irt/generators/admin_subsite.irt +27 -0
- data/test/irt/generators/assets.irt +16 -0
- data/test/irt/generators/controller.irt +6 -0
- data/test/irt/generators/front_controller.irt +30 -0
- data/test/irt/generators/helper.rb +31 -0
- data/test/irt/generators/model.irt +28 -0
- data/test/irt/generators/partials/_account_user_model_tests.rb +21 -0
- data/test/irt/generators/partials/_accounts_users_controller_tests.rb +15 -0
- data/test/irt/generators/partials/_default_user_model_tests.rb +21 -0
- data/test/irt/generators/partials/_default_users_controller_tests.rb +16 -0
- data/test/irt/generators/partials/_house_controller_tests.rb +15 -0
- data/test/irt/generators/partials/_house_model_tests.rb +18 -0
- data/test/irt/generators/partials/_subsite_taglib_admin.rb +4 -0
- data/test/irt/generators/partials/_subsite_taglib_admin_invite_only.rb +3 -0
- data/test/irt/generators/partials/_subsite_taglib_noopt.rb +4 -0
- data/test/irt/generators/partials/_subsite_taglib_variables.rb +27 -0
- data/test/irt/generators/partials/_user_mailer_tests.rb +19 -0
- data/test/irt/generators/rapid.irt +29 -0
- data/test/irt/generators/resource.irt +8 -0
- data/test/irt/generators/subsite.irt +52 -0
- data/test/irt/generators/subsite_taglib.irt +23 -0
- data/test/irt/generators/test_framework.irt +62 -0
- data/test/irt/generators/user_controller.irt +10 -0
- data/test/irt/generators/user_mailer.irt +20 -0
- data/test/irt/generators/user_model.irt +10 -0
- data/test/irt/generators/user_resource.irt +14 -0
- data/test/irt/readme.txt +7 -0
- data/test/permissions/models/models.rb +27 -24
- data/test/permissions/test_permissions.rb +104 -104
- metadata +239 -217
- data/lib/active_record/association_reflection.rb +0 -20
- data/lib/active_record/viewhints_validations_interceptor.rb +0 -9
- data/lib/hobo/accessible_associations.rb +0 -183
- data/lib/hobo/authentication_support.rb +0 -131
- data/lib/hobo/generator.rb +0 -26
- data/lib/hobo/guest.rb +0 -25
- data/lib/hobo/include_in_save.rb +0 -55
- data/lib/hobo/lifecycles.rb +0 -137
- data/lib/hobo/lifecycles/actions.rb +0 -142
- data/lib/hobo/lifecycles/creator.rb +0 -72
- data/lib/hobo/lifecycles/lifecycle.rb +0 -249
- data/lib/hobo/lifecycles/state.rb +0 -22
- data/lib/hobo/lifecycles/transition.rb +0 -70
- data/lib/hobo/model_router.rb +0 -290
- data/lib/hobo/permissions.rb +0 -451
- data/lib/hobo/permissions/associations.rb +0 -175
- data/lib/hobo/rapid_helper.rb +0 -157
- data/lib/hobo/scopes.rb +0 -43
- data/lib/hobo/scopes/apply_scopes.rb +0 -23
- data/lib/hobo/scopes/association_proxy_extensions.rb +0 -62
- data/lib/hobo/scopes/automatic_scopes.rb +0 -421
- data/lib/hobo/scopes/named_scope_extensions.rb +0 -39
- data/lib/hobo/tasks/rails.rb +0 -4
- data/lib/hobo/translations.rb +0 -93
- data/lib/hobo/undefined_access_error.rb +0 -5
- data/lib/hobo/user.rb +0 -182
- data/lib/hobo/view_hints.rb +0 -115
- data/rails/init.rb +0 -10
- data/rails_generators/hobo/USAGE +0 -4
- data/rails_generators/hobo/hobo_generator.rb +0 -53
- data/rails_generators/hobo/templates/application.dryml +0 -1
- data/rails_generators/hobo/templates/initializer.rb +0 -2
- data/rails_generators/hobo_admin_site/USAGE +0 -16
- data/rails_generators/hobo_admin_site/hobo_admin_site_generator.rb +0 -45
- data/rails_generators/hobo_admin_site/templates/admin.css +0 -2
- data/rails_generators/hobo_admin_site/templates/users_index.dryml +0 -5
- data/rails_generators/hobo_front_controller/hobo_front_controller_generator.rb +0 -95
- data/rails_generators/hobo_front_controller/templates/functional_test.rb +0 -8
- data/rails_generators/hobo_front_controller/templates/helper.rb +0 -2
- data/rails_generators/hobo_model/USAGE +0 -25
- data/rails_generators/hobo_model/hobo_model_generator.rb +0 -43
- data/rails_generators/hobo_model/templates/fixtures.yml +0 -6
- data/rails_generators/hobo_model/templates/hints.rb +0 -7
- data/rails_generators/hobo_model/templates/unit_test.rb +0 -8
- data/rails_generators/hobo_model_controller/USAGE +0 -30
- data/rails_generators/hobo_model_controller/hobo_model_controller_generator.rb +0 -46
- data/rails_generators/hobo_model_controller/templates/controller.rb +0 -7
- data/rails_generators/hobo_model_controller/templates/functional_test.rb +0 -8
- data/rails_generators/hobo_model_controller/templates/helper.rb +0 -2
- data/rails_generators/hobo_model_resource/USAGE +0 -38
- data/rails_generators/hobo_model_resource/hobo_model_resource_generator.rb +0 -73
- data/rails_generators/hobo_model_resource/templates/controller.rb +0 -7
- data/rails_generators/hobo_model_resource/templates/functional_test.rb +0 -8
- data/rails_generators/hobo_model_resource/templates/helper.rb +0 -2
- data/rails_generators/hobo_rapid/hobo_rapid_generator.rb +0 -94
- data/rails_generators/hobo_subsite/USAGE +0 -16
- data/rails_generators/hobo_subsite/hobo_subsite_generator.rb +0 -73
- data/rails_generators/hobo_subsite/templates/site_taglib.dryml +0 -13
- data/rails_generators/hobo_user_controller/USAGE +0 -34
- data/rails_generators/hobo_user_controller/hobo_user_controller_generator.rb +0 -65
- data/rails_generators/hobo_user_controller/templates/controller.rb +0 -29
- data/rails_generators/hobo_user_controller/templates/functional_test.rb +0 -8
- data/rails_generators/hobo_user_controller/templates/helper.rb +0 -2
- data/rails_generators/hobo_user_model/USAGE +0 -16
- data/rails_generators/hobo_user_model/hobo_user_model_generator.rb +0 -46
- data/rails_generators/hobo_user_model/templates/fixtures.yml +0 -19
- data/rails_generators/hobo_user_model/templates/mailer.rb +0 -29
- data/rails_generators/hobo_user_model/templates/unit_test.rb +0 -8
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/taglibs/rapid_translations.dryml +0 -36
- data/tasks/environments.rake +0 -19
- data/tasks/hobo_tasks.rake +0 -58
- data/test/generators/test_generator_helper.rb +0 -29
- data/test/generators/test_helper.rb +0 -1
- data/test/generators/test_hobo_model_controller_generator.rb +0 -56
@@ -0,0 +1,166 @@
|
|
1
|
+
module Hobo
|
2
|
+
module Rapid
|
3
|
+
module Helper
|
4
|
+
|
5
|
+
def comma_split(x)
|
6
|
+
case x
|
7
|
+
when nil
|
8
|
+
[]
|
9
|
+
when String
|
10
|
+
x.strip.split(/\s*,\s*/)
|
11
|
+
else
|
12
|
+
x.compact.map{|e| comma_split(e)}.flatten
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def rapid_build_callbacks(options)
|
17
|
+
callbacks = {}
|
18
|
+
options.each do |callback, code|
|
19
|
+
if AJAX_CALLBACKS.include?(callback.to_sym)
|
20
|
+
name = 'on' + callback.to_s.capitalize
|
21
|
+
callbacks[name] = "function(request){#{code}}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
callbacks
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def options_for_hobo_ajax(options)
|
29
|
+
js_options = rapid_build_callbacks(options)
|
30
|
+
|
31
|
+
js_options['asynchronous'] = false if options[:type] == :synchronous
|
32
|
+
js_options['method'] = method_option_to_s(options[:method]) if options[:method]
|
33
|
+
js_options['evalScripts'] = false if options[:script] == false
|
34
|
+
js_options['form'] = options[:form] if options[:form]
|
35
|
+
js_options['params'] = make_params_js(options[:params]) if options[:params]
|
36
|
+
js_options['resultUpdate'] = js_result_updates(options[:result_update]) if options[:result_update]
|
37
|
+
js_options['resetForm'] = options[:reset_form] if options.has_key?(:reset_form)
|
38
|
+
js_options['refocusForm'] = options[:refocus_form] if options.has_key?(:refocus_form)
|
39
|
+
js_options['spinnerNextTo'] = js_str(options[:spinner_next_to]) if options.has_key?(:spinner_next_to)
|
40
|
+
js_options['message'] = js_str(options[:message]) if options[:message]
|
41
|
+
|
42
|
+
js_options.empty? ? nil : options_for_javascript(js_options)
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def js_updates(updates)
|
47
|
+
return '[]' unless updates
|
48
|
+
updates = [updates] unless updates.is_a? Array
|
49
|
+
updates = comma_split(updates).map do |u|
|
50
|
+
if u.to_s == "self"
|
51
|
+
"Hobo.partFor(this)"
|
52
|
+
else
|
53
|
+
js_str(u)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
"[#{updates * ', '}]"
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def js_result_updates(updates)
|
61
|
+
return '[]' unless updates
|
62
|
+
updates = [updates] unless updates.is_a? Array
|
63
|
+
pairs = comma_split(updates).map &it.split(/\s*=\s*/)
|
64
|
+
'[' + pairs.map{|p| "{id: #{js_str(p[0])}, result: #{js_str(p[1])}}"}.join(", ") + ']'
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def ajax_updater(url_or_form, update, options={})
|
69
|
+
options ||= {}
|
70
|
+
options = options.symbolize_keys
|
71
|
+
|
72
|
+
target = if url_or_form == :post_form
|
73
|
+
target = "this"
|
74
|
+
else
|
75
|
+
js_str(url_or_form)
|
76
|
+
end
|
77
|
+
js_options = options_for_hobo_ajax(options)
|
78
|
+
args = [target, js_updates(update), js_options].compact
|
79
|
+
|
80
|
+
confirm = options.delete(:confirm)
|
81
|
+
|
82
|
+
func = "Hobo.ajaxRequest(#{args * ', '})"
|
83
|
+
if confirm
|
84
|
+
"if (confirm(#{js_str(confirm)})) { #{func} }"
|
85
|
+
else
|
86
|
+
func
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
def a_or_an(word)
|
92
|
+
if word =~ /^[aeiouh]/
|
93
|
+
"an #{word}"
|
94
|
+
else
|
95
|
+
"a #{word}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
def no_break(s)
|
101
|
+
s = new_context { yield } if block_given?
|
102
|
+
s.gsub(' ', ' ')
|
103
|
+
end
|
104
|
+
|
105
|
+
# returns the number of items in the collection. See LH #889
|
106
|
+
def collection_count
|
107
|
+
this.try.to_int || this.try.total_entries || (this.try.loaded? && this.try.length) || this.try.count || this.try.length
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
def in_place_editor(attributes, this=nil)
|
112
|
+
blank_message = attributes.delete(:blank_message) ||
|
113
|
+
t('hobo.in_place_editor.click_to_edit', :default => '(click to edit)')
|
114
|
+
|
115
|
+
attributes = add_classes(attributes, "in-place-edit", model_id_class(this_parent, this_field))
|
116
|
+
attributes.update(:hobo_blank_message => blank_message,
|
117
|
+
:if_blank => blank_message,
|
118
|
+
:no_wrapper => false)
|
119
|
+
|
120
|
+
edit_text = this._?.to_s
|
121
|
+
attributes.update(:hobo_edit_text => edit_text) unless edit_text.nil?
|
122
|
+
|
123
|
+
update = attributes.delete(:update)
|
124
|
+
attributes[:hobo_update] = update if update
|
125
|
+
|
126
|
+
view(attributes)
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
AJAX_CALLBACKS = [ :before, :success, :failure, :complete ]
|
132
|
+
|
133
|
+
AJAX_ATTRS = AJAX_CALLBACKS + [ :update, :type, :method,
|
134
|
+
:script, :form, :params, :confirm, :message,
|
135
|
+
:reset_form, :refocus_form, :result_update, :spinner_next_to ]
|
136
|
+
|
137
|
+
|
138
|
+
def through_collection_names(object=this)
|
139
|
+
object.class.reflections.values.select do |refl|
|
140
|
+
refl.macro == :has_many && refl.options[:through]
|
141
|
+
end.map {|x| x.options[:through]}
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
def non_through_collections(object=this)
|
146
|
+
names = object.class.reflections.values.select do |refl|
|
147
|
+
refl.macro == :has_many
|
148
|
+
end.*.name
|
149
|
+
|
150
|
+
names - through_collection_names
|
151
|
+
end
|
152
|
+
|
153
|
+
def standard_fields(model, include_timestamps=false)
|
154
|
+
fields = model.attr_order.*.to_s & model.content_columns.*.name
|
155
|
+
fields -= %w{created_at updated_at created_on updated_on deleted_at} unless include_timestamps
|
156
|
+
fields.reject! { |f| model.never_show? f }
|
157
|
+
fields
|
158
|
+
end
|
159
|
+
|
160
|
+
def current_time
|
161
|
+
Time.zone ? Time.zone.now : Time.now
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
<!--
|
2
2
|
|
3
|
-
The Rapid tag library makes web development go fast. The Rapid tag library is your friend.
|
3
|
+
The Rapid tag library makes web development go fast. The Rapid tag library is your friend.
|
4
4
|
|
5
5
|
(This taglib defines no tags - it just includes all the other taglibs. Move along. Nothing to see here.)
|
6
6
|
|
7
7
|
-->
|
8
8
|
|
9
|
-
<include module="Hobo::
|
10
|
-
<include module="Hobo::
|
11
|
-
<include module="Hobo::Translations"/>
|
9
|
+
<include module="Hobo::Helper"/>
|
10
|
+
<include module="Hobo::Rapid::Helper"/>
|
11
|
+
<include module="Hobo::Helper::Translations"/>
|
12
12
|
|
13
13
|
<include src="rapid_core"/>
|
14
14
|
<include src="rapid_support"/>
|
@@ -21,4 +21,5 @@ The Rapid tag library makes web development go fast. The Rapid tag library is yo
|
|
21
21
|
<include src="rapid_generics"/>
|
22
22
|
<include src="rapid_lifecycles"/>
|
23
23
|
<include src="rapid_summary"/>
|
24
|
-
<include src="rapid_user_pages"/>
|
24
|
+
<include src="rapid_user_pages"/>
|
25
|
+
<include src="rapid_i18n"/>
|
@@ -1,23 +1,26 @@
|
|
1
|
+
<!-- Core Rapid tags and tags that don't belong anywhere else. -->
|
1
2
|
|
2
3
|
<!-- Renders a table with one row per field, where each row contains a `<th>` with the field name, and a `<td>` with (by default)
|
3
4
|
a `<view>` of the field.
|
4
|
-
|
5
|
+
|
5
6
|
### Attributes
|
6
7
|
|
7
8
|
- fields: Comma separated list of field names to display. Defaults to the fields returned by the `standard_fields` helper. That is, all fields apart from IDs and timestamps.
|
8
|
-
|
9
|
+
|
9
10
|
- force-all: All non-viewable fields will be skipped unless this attribute is given
|
10
|
-
|
11
|
+
|
11
12
|
- skip: Comma separated list of fields to exclude
|
12
13
|
|
13
14
|
- tag: The name of a tag to use inside the `<td>` to display the value. Defaults to `view`
|
14
|
-
|
15
|
+
|
15
16
|
- no-edit: Controls the behavior of `<input>` tags when the user doesn't have edit permission for a field.
|
16
17
|
- view: render the current value using the `<view>` tag
|
17
18
|
- disable: render the input as normal, but add HTML's `disabled` attribute
|
18
19
|
- skip: render nothing at all. This will omit the entire row (including the label)
|
19
20
|
- ignore: render the input normally. That is, don't even perform the edit check.
|
20
21
|
|
22
|
+
- no-blanks: (boolean) Controls the behavior of `<view>` tags. The entire row (including the label) will be omitted if `this` is blank. Default false.
|
23
|
+
|
21
24
|
### Example
|
22
25
|
|
23
26
|
<field-list fields="first-name, last-name, city">
|
@@ -27,14 +30,14 @@
|
|
27
30
|
</field-list>
|
28
31
|
|
29
32
|
-->
|
30
|
-
<def tag="field-list" attrs="tag, no-edit">
|
33
|
+
<def tag="field-list" attrs="tag, no-edit, no-blanks">
|
31
34
|
<% tag ||= scope.in_form ? "input" : "view"; no_edit ||= "skip" %>
|
32
35
|
<labelled-item-list merge-attrs="&attributes - attrs_for(:with_fields)">
|
33
36
|
<with-fields merge-attrs="&attributes & attrs_for(:with_fields)">
|
34
|
-
<% field_name = this_field_name
|
37
|
+
<% field_name = this_field_name
|
35
38
|
input_attrs = {:no_edit => no_edit} if tag == "input"
|
36
39
|
-%>
|
37
|
-
<labelled-item unless="&tag == 'input' && no_edit == 'skip' && !can_edit?">
|
40
|
+
<labelled-item unless="&(tag == 'input' && no_edit == 'skip' && !can_edit?) || (tag == 'view' && no_blanks && this.blank?)">
|
38
41
|
<item-label param="#{scope.field_name.to_s.sub('?', '').gsub('.', '-')}-label" unless="&field_name.blank?">
|
39
42
|
<do param="label"><%= field_name %></do>
|
40
43
|
</item-label>
|
@@ -48,13 +51,13 @@
|
|
48
51
|
</def>
|
49
52
|
|
50
53
|
<!-- Used to render nil values. By default renders "(Not Available)"
|
51
|
-
|
54
|
+
|
52
55
|
### Usage
|
53
56
|
|
54
57
|
Redefine in your app to have nil values displayed differently, e.g.:
|
55
58
|
|
56
59
|
<def tag="nil-view">-</def>
|
57
|
-
|
60
|
+
|
58
61
|
-->
|
59
62
|
<def tag="nil-view"><%= scope.nil_view || "(Not Available)" %></def>
|
60
63
|
|
@@ -107,7 +110,7 @@ This will use `<input/>` as the tag in each table cell instead of `<view/>`
|
|
107
110
|
<thead if="&all_parameters[:thead] || fields" param>
|
108
111
|
<tr param="field-heading-row">
|
109
112
|
<with-field-names merge-attrs="&all_attributes & attrs_for(:with_fields)">
|
110
|
-
<th param="#{scope.field_name}-heading"><%=
|
113
|
+
<th param="#{scope.field_name}-heading"><%= this.member_class.human_attribute_name(scope.field_name) if scope %></th>
|
111
114
|
</with-field-names>
|
112
115
|
<th if="&all_parameters[:controls]" class="controls"/>
|
113
116
|
</tr>
|
@@ -121,12 +124,14 @@ This will use `<input/>` as the tag in each table cell instead of `<view/>`
|
|
121
124
|
<td param="#{scope.field_name.to_s.sub('?', '').gsub('.', '-')}-view"><call-tag tag="&field_tag"/></td>
|
122
125
|
</with-fields>
|
123
126
|
<td class="controls" param="controls" if="&all_parameters[:controls]">
|
124
|
-
<a param="edit-link" action="edit" if="&can_edit?"
|
127
|
+
<a param="edit-link" action="edit" if="&can_edit?">
|
128
|
+
<t key="hobo.actions.edit_control">Edit</t>
|
129
|
+
</a>
|
125
130
|
<delete-button param/>
|
126
131
|
</td>
|
127
132
|
</if>
|
128
133
|
</tr>
|
129
|
-
</repeat>
|
134
|
+
</repeat>
|
130
135
|
</tbody>
|
131
136
|
<tfoot if="&all_parameters[:tfoot]" param/>
|
132
137
|
<% end %>
|
@@ -154,27 +159,38 @@ Provides a short hand way of displaying images in public/images
|
|
154
159
|
|
155
160
|
|
156
161
|
<!-- Renders some standard JavaScript code that various features of the Rapid library rely on. This tag would typicallu be called from your `<page>` tag. The default Rapid pages include this already. -->
|
157
|
-
<def tag="hobo-rapid-javascripts"
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
162
|
+
<def tag="hobo-rapid-javascripts">
|
163
|
+
<script type="text/javascript" param="default"><%=
|
164
|
+
res = 'var hoboParts = {};'
|
165
|
+
# FIXME: This should interrogate the model-router - not the models
|
166
|
+
unless Hobo::Model.all_models.empty?
|
167
|
+
# Tell JS code how to pluralize names, unless they follow the simple rule
|
168
|
+
names = Hobo::Model.all_models.map do |m|
|
169
|
+
m = m.name.underscore
|
170
|
+
"#{m}: '#{m.pluralize}'" unless m.pluralize == m + 's'
|
171
|
+
end.compact
|
172
|
+
res << "var pluralisations = {#{names * ', '}}; "
|
173
|
+
end
|
174
|
+
base = [base_url, subsite].compact.join("/")
|
175
|
+
res << "urlBase = '#{base}'; hoboPagePath = '#{request.fullpath}'"
|
176
|
+
if protect_against_forgery?
|
177
|
+
res << "; formAuthToken = { name: '#{request_forgery_protection_token}', value: '#{form_authenticity_token}' }"
|
178
|
+
end
|
179
|
+
res
|
180
|
+
%></script>
|
181
|
+
</def>
|
182
|
+
|
183
|
+
|
184
|
+
<def tag="part-contexts-javascripts">
|
185
|
+
<% unless (storage = part_contexts_storage).blank? %>
|
186
|
+
<script type="text/javascript"><%=
|
187
|
+
storage
|
188
|
+
%></script>
|
189
|
+
<% end %>
|
190
|
+
</def>
|
175
191
|
|
176
192
|
<!-- Renders the name of the current context using a variety of methods.
|
177
|
-
|
193
|
+
|
178
194
|
### Details
|
179
195
|
|
180
196
|
- Equivalent to `<nil-view>` if `this` is nil
|
@@ -186,9 +202,9 @@ Provides a short hand way of displaying images in public/images
|
|
186
202
|
### Attributes
|
187
203
|
|
188
204
|
- if-present: if given, nothing at all will be rendered for nil values (as opposed to rendering `<nil-view>`)
|
189
|
-
|
205
|
+
|
190
206
|
-->
|
191
|
-
<def tag="name" attrs="if-present"><%=
|
207
|
+
<def tag="name" attrs="if-present"><%=
|
192
208
|
if this.nil?
|
193
209
|
nil_view unless if_present
|
194
210
|
else
|
@@ -206,44 +222,46 @@ Provides a short hand way of displaying images in public/images
|
|
206
222
|
|
207
223
|
|
208
224
|
<!-- Renders a human readable version of the type of the context
|
209
|
-
|
225
|
+
|
210
226
|
### Details
|
211
227
|
|
212
228
|
- If `this` is already a class, the name of that class is used
|
213
229
|
- Otherwise, first `this.member_class` (for collections), then `this.class` are tried
|
214
230
|
- By default the name is titleised and singular.
|
215
|
-
|
231
|
+
|
216
232
|
### Attributes
|
217
233
|
|
218
234
|
- plural: pluralise the name
|
219
235
|
- lowercase: render the name in all lower case
|
220
|
-
- dasherize: render the name in lower case with dashes instead of spaces.
|
236
|
+
- dasherize: render the name in lower case with dashes instead of spaces.
|
221
237
|
|
222
238
|
-->
|
223
239
|
<def tag="type-name" attrs="plural, lowercase, dasherize"><%=
|
224
240
|
type ||= (this if this.is_a?(Class)) || this.try.member_class || this.class
|
225
|
-
|
226
|
-
name = type.respond_to?(:
|
241
|
+
|
242
|
+
name = type.respond_to?(:model_name) ? type.model_name.human : type.name
|
227
243
|
name = dasherize ? name.underscore.dasherize : name.titleize
|
228
244
|
name = name.pluralize if plural
|
229
245
|
name = name.downcase if lowercase
|
230
246
|
name
|
231
247
|
%></def>
|
232
|
-
|
248
|
+
|
233
249
|
|
234
250
|
<!-- Renders a human readable name of a collection
|
235
|
-
|
251
|
+
|
252
|
+
Use this tag for en locale only. Use human-collection-name for i18n.
|
253
|
+
|
236
254
|
### Details
|
237
255
|
|
238
256
|
- Uses `this.origin_attribute` as the name.
|
239
257
|
- Falls back to `<type-name>` otherwise.
|
240
258
|
- By default the name is titleised and plural.
|
241
|
-
|
259
|
+
|
242
260
|
### Attributes
|
243
261
|
|
244
262
|
- singular: singularise the name
|
245
263
|
- lowercase: render the name in all lower case
|
246
|
-
- dasherize: render the name in lower case with dashes instead of spaces.
|
264
|
+
- dasherize: render the name in lower case with dashes instead of spaces.
|
247
265
|
|
248
266
|
-->
|
249
267
|
<def tag="collection-name" attrs="singular, lowercase, dasherize"><%=
|
@@ -284,7 +302,7 @@ An action can be provided for an alternative show page:
|
|
284
302
|
<a with="&blog_post" action="edit">Edit Post</a> -> <a href="/blog_posts/1/edit">Edit Post</a>
|
285
303
|
|
286
304
|
Or a new page if the context is a class:
|
287
|
-
|
305
|
+
|
288
306
|
<a with="&BlogPost" action="new">New Blog Post</a> -> <a href="/blog_posts/new">New Blog Post</a>
|
289
307
|
|
290
308
|
### Additional Features
|
@@ -324,16 +342,16 @@ Or a new page if the context is a class:
|
|
324
342
|
-->
|
325
343
|
<def tag="a" attrs="action, to, params, query-params, href, format, subsite, force"><%=
|
326
344
|
content = parameters.default
|
327
|
-
|
345
|
+
|
328
346
|
params = self.query_params.merge(params || HashWithIndifferentAccess.new) if query_params
|
329
|
-
|
347
|
+
|
330
348
|
if href || attributes[:name]
|
331
349
|
# Regular link
|
332
350
|
href += "?" + params.map { |n, v| "#{n}=#{v}" }.join('&') if !params.blank?
|
333
351
|
element(:a, attributes.update(:href => href), content)
|
334
352
|
else
|
335
353
|
target = to || this
|
336
|
-
|
354
|
+
|
337
355
|
if target.nil?
|
338
356
|
Dryml.last_if = false
|
339
357
|
nil_view
|
@@ -342,7 +360,7 @@ Or a new page if the context is a class:
|
|
342
360
|
new_record = target.new
|
343
361
|
new_record.set_creator(current_user)
|
344
362
|
href = object_url(target, "new", params._?.merge(:subsite => subsite))
|
345
|
-
|
363
|
+
|
346
364
|
if href && (force || can_create?(new_record))
|
347
365
|
new_class_name = if target.respond_to?(:proxy_reflection)
|
348
366
|
target.proxy_reflection.klass.name
|
@@ -362,17 +380,17 @@ Or a new page if the context is a class:
|
|
362
380
|
# Link to an existing object
|
363
381
|
|
364
382
|
content = name if content.blank?
|
365
|
-
|
366
|
-
href = object_url(target, action, (params || {}).merge(:subsite => subsite))
|
383
|
+
|
384
|
+
href = object_url(target, action, (params || {}).merge(:subsite => subsite)) unless (action.nil? && target.try.new_record?)
|
367
385
|
if href.nil?
|
368
|
-
# This target is registered with
|
386
|
+
# This target is registered with Hobo::Routes as not linkable
|
369
387
|
content
|
370
388
|
else
|
371
389
|
css_class = target.try.origin_attribute || target.class.name.underscore.dasherize
|
372
390
|
add_classes!(attributes, "#{css_class}-link")
|
373
|
-
|
391
|
+
|
374
392
|
href.sub!(/\?|$/, ".#{format}\\0") unless format.blank?
|
375
|
-
|
393
|
+
|
376
394
|
# Set default link text if none given
|
377
395
|
element(:a, attributes.update(:href => href), content)
|
378
396
|
end
|
@@ -416,14 +434,14 @@ Assuming the context is a blog post...
|
|
416
434
|
<def tag="view" attrs="inline, block, if-blank, no-wrapper, truncate"><%=
|
417
435
|
raise Hobo::PermissionDeniedError, "view of non-viewable field '#{this_field}' of #{this_parent.typed_id rescue this_parent}" unless
|
418
436
|
can_view?
|
419
|
-
|
437
|
+
|
420
438
|
res = if this.nil? && if_blank.nil?
|
421
439
|
this_type.is_a?(Class) && this_type <= String ? "" : nil_view
|
422
440
|
elsif (refl = this_field_reflection) && refl.macro == :has_many
|
423
441
|
collection_view(attributes)
|
424
442
|
else
|
425
443
|
view_tag = find_polymorphic_tag("view")
|
426
|
-
|
444
|
+
|
427
445
|
if view_tag == "view" # i.e. it didn't find a type specific tag
|
428
446
|
if this.respond_to?(:to_html)
|
429
447
|
this.to_html(scope.xmldoctype)
|
@@ -435,19 +453,19 @@ Assuming the context is a blog post...
|
|
435
453
|
|
436
454
|
view_attrs = attrs_for(view_tag)
|
437
455
|
the_view = send(view_tag, attrs & view_attrs)
|
438
|
-
|
456
|
+
|
439
457
|
the_view = if_blank if if_blank && the_view.blank?
|
440
458
|
|
441
459
|
truncate = 30 if truncate == true
|
442
460
|
the_view = self.truncate(the_view, :length => truncate.to_i) if truncate
|
443
461
|
the_view = the_view.strip
|
444
|
-
|
462
|
+
|
445
463
|
if no_wrapper
|
446
464
|
the_view
|
447
465
|
else
|
448
466
|
wrapper = if inline
|
449
467
|
:span
|
450
|
-
elsif block || this_type <= HoboFields::Text
|
468
|
+
elsif block || this_type <= HoboFields::Types::Text
|
451
469
|
:div
|
452
470
|
else
|
453
471
|
:span
|
@@ -464,45 +482,38 @@ Assuming the context is a blog post...
|
|
464
482
|
<def tag="collection-view" polymorphic><links-for-collection merge-attrs/></def>
|
465
483
|
|
466
484
|
<!-- Renders a comma separated list of links (`<a>`), or "(none)" if the list is empty -->
|
467
|
-
<def tag="links-for-collection"><%= this.empty? ? "(none)" : context_map { a }.
|
485
|
+
<def tag="links-for-collection"><%= this.empty? ? "(none)" : context_map { a }.safe_join(", ") %></def>
|
468
486
|
|
469
|
-
<!-- Renders `
|
470
|
-
<def tag="view" for="
|
487
|
+
<!-- Renders `this` in localized :default format. `format` can be a symbol representing a locale key or a standard format string (see strftime) -->
|
488
|
+
<def tag="view" for="date" attrs="format"><%= this && (format||= :default) && I18n.backend.localize(I18n.locale, this, format) %></def>
|
471
489
|
|
472
|
-
<!-- Renders `
|
473
|
-
<def tag="view" for="
|
490
|
+
<!-- Renders `this` in localized :default format. `format` can be a symbol representing a Time::DATE_FORMATS or a standard format string (see strftime) -->
|
491
|
+
<def tag="view" for="time" attrs="format"><%= this && (format||= :time) && (format.is_a?(Symbol) ? this.to_s(format) : this.strftime(format) ) %></def>
|
474
492
|
|
475
|
-
<!-- Renders `
|
476
|
-
<def tag="view" for="
|
493
|
+
<!-- Renders `this` in localized :default format. `format` can be a symbol representing a locale key or a standard format string (see strftime) -->
|
494
|
+
<def tag="view" for="datetime" attrs="format"><%= this && (format||= :default) && I18n.backend.localize(I18n.locale, this, format) %></def>
|
477
495
|
|
478
|
-
<!-- Renders `this
|
479
|
-
<def tag="view" for="Numeric" attrs="format"><%= format ? format % this : this
|
496
|
+
<!-- Renders localized `number_with_delimiter this`, or `format % this` if the `format` attribute is given -->
|
497
|
+
<def tag="view" for="Numeric" attrs="format"><%= format ? format % this : number_with_delimiter(this) %></def>
|
480
498
|
|
481
499
|
<!-- Renders `this` with HTML escaping and newlines replaced with `<br>` tags -->
|
482
|
-
<def tag="view" for="string"><%=
|
500
|
+
<def tag="view" for="string"><%=
|
483
501
|
if !(this.class == String) && this.respond_to?(:to_html) # workaround for Maruku which adds String#to_html : (
|
484
502
|
this.to_html(scope.xmldoctype)
|
485
503
|
else
|
486
|
-
h(this).gsub("\n", "<br#{scope.xmldoctype ? ' /' : ''}>")
|
504
|
+
h(this).gsub("\n", "<br#{scope.xmldoctype ? ' /' : ''}>")
|
487
505
|
end
|
488
506
|
%></def>
|
489
507
|
|
490
|
-
<!-- Renders 'Yes' for true and 'No' for false
|
491
|
-
<def tag="view" for="boolean"><%= this ?
|
508
|
+
<!-- Renders 'Yes' for true and 'No' for false -->
|
509
|
+
<def tag="view" for="boolean"><%= this ? t('hobo.boolean_yes', :default => 'Yes') : t('hobo.boolean_no', :default => 'No') %></def>
|
492
510
|
|
493
511
|
<!-- Renders a link (`<a>`) to `this` -->
|
494
512
|
<def tag="view" for="ActiveRecord::Base"><a merge-attrs/></def>
|
495
513
|
|
496
|
-
<!-- Renders `this.to_s` with localization support -->
|
497
|
-
<def tag="view" for="HoboFields::LifecycleState">
|
498
|
-
<span class='#{this.class.parent.name.downcase}-states #{this.class.parent.name.downcase}-state-#{this.to_s.downcase} state-#{this.to_s.downcase}'>
|
499
|
-
<ht key='#{this.class.parent.name.tableize}.lifecycle_states.#{this.to_s.downcase}'><%= this.to_s %></ht>
|
500
|
-
</span>
|
501
|
-
</def>
|
502
|
-
|
503
514
|
|
504
515
|
<!--
|
505
|
-
A convenience tag used to output a count
|
516
|
+
A convenience tag used to output a count summary with a correctly localized and pluralised label. Works with any kind of collection such as an `ActiveRecord` association or an array.
|
506
517
|
|
507
518
|
### Usage
|
508
519
|
|
@@ -514,12 +525,47 @@ The label can be customised using the `label` attribute, e.g.
|
|
514
525
|
|
515
526
|
<count:comments label="blog post comment"/> -> <span class="count">12 blog post comments</span>
|
516
527
|
|
528
|
+
You can pass a summary attribute, which will generate a complete localized sentence. It allows 2 options:
|
529
|
+
- boolean (e.g. `<count summary/>`): it will lookup the 'tags.count.default' key in the locale file.
|
530
|
+
If the lookup fails, it will fallback to the english default sentences consistent with the count.
|
531
|
+
- String (e.g. `<count summary="offer"/>`): it will lookup the 'tags.count.offer' key in the locale file.
|
532
|
+
If the lookup fails, it will fallback to the english default sentences consistent with the count.
|
533
|
+
|
534
|
+
### Examples
|
535
|
+
|
536
|
+
it:
|
537
|
+
tags:
|
538
|
+
count:
|
539
|
+
default:
|
540
|
+
zero: "Non ci sono {{label}}"
|
541
|
+
one: "C'è solo 1 {{label}}"
|
542
|
+
other: "Ci sono {{count}} {{label}}"
|
543
|
+
choice:
|
544
|
+
zero: "Non ci sono {{label}} da scegliere"
|
545
|
+
one: "Puoi scegliere solo una {{label}}"
|
546
|
+
other: "Puoi scegliere tra {{count}} {{label}}"
|
547
|
+
|
548
|
+
with :en locale and boolean summary (internal defaults)
|
549
|
+
<count:comments summary/> -> <span class="count">There is 1 Comment</span>
|
550
|
+
<count:viewings summary/> -> <span class="count">There are 3 Viewings</span>
|
551
|
+
(note: just add the locale english strings to use like the following examples)
|
552
|
+
|
553
|
+
with :it locale and boolean summary (key "tags.count.default")
|
554
|
+
<count:comments summary/>
|
555
|
+
-> count => 0 -> <span class="count">Non ci sono Commenti</span>
|
556
|
+
-> count => 1 -> <span class="count">C'è solo 1 Commento</span>
|
557
|
+
-> count => 5 -> <span class="count">Ci sono 5 Commenti</span>
|
558
|
+
|
559
|
+
with :it locale and summary="choice" (key "tags.count.choice")
|
560
|
+
<count:comments summary="choice"/>
|
561
|
+
-> count => 0 -> <span class="count">Non ci sono Commenti da scegliere</span>
|
562
|
+
-> count => 1 -> <span class="count">Puoi scegliere solo 1 Commento</span>
|
563
|
+
-> count => 5 -> <span class="count">Puoi scegliere tra 5 Commenti</span>
|
564
|
+
|
517
565
|
### Additional Notes
|
518
566
|
|
519
|
-
*
|
567
|
+
* The `prefix` attribute is deprecated: use summary instead.
|
520
568
|
|
521
|
-
There <count:comments prefix="are"/> -> There <span class="count">is 1 Comment</span>
|
522
|
-
There <count:viewings prefix="are"/> -> There <span class="count">are 3 Viewings</span>
|
523
569
|
* Use the `lowercase` attribute to force the generated label to be lowercase:
|
524
570
|
|
525
571
|
<count:comments lowercase/> -> <span class="count">1 comment</span>
|
@@ -527,38 +573,44 @@ The label can be customised using the `label` attribute, e.g.
|
|
527
573
|
|
528
574
|
<count:comments if-any/><else>There are no comments</else>
|
529
575
|
-->
|
530
|
-
<def tag="count" attrs="
|
576
|
+
<def tag="count" attrs="summary, label, if-any, lowercase, prefix"><span class="count"><%=
|
531
577
|
raise Exception.new("asked for count of a string") if this.is_a?(String)
|
532
|
-
|
533
|
-
|
578
|
+
Rails.logger.warn('The "prefix" attribute is deprecated: please, use a locale string') unless prefix.blank?
|
579
|
+
|
580
|
+
c = collection_count
|
534
581
|
|
535
|
-
label
|
536
|
-
|
537
|
-
|
538
|
-
this.
|
582
|
+
# generated label will be pluralized
|
583
|
+
label ||= case
|
584
|
+
when this.is_a?(Class)
|
585
|
+
this.model_name.human(:count=>c)
|
586
|
+
when (attr = this.try.origin_attribute)
|
587
|
+
this_parent.class.human_attribute_name(attr, :count=>c)
|
539
588
|
else
|
540
|
-
this.member_class.
|
541
|
-
end
|
589
|
+
this.member_class.model_name.human(:count=>c)
|
590
|
+
end
|
542
591
|
|
543
592
|
label = label.downcase if lowercase
|
544
|
-
|
593
|
+
|
545
594
|
Dryml.last_if = c > 0 if if_any
|
546
595
|
if if_any && c == 0
|
547
596
|
""
|
548
597
|
else
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
598
|
+
if summary.blank? # old behaviour
|
599
|
+
main = label.blank? ? c : "#{c} #{label}"
|
600
|
+
if prefix.in? %w(are is)
|
601
|
+
prefix = c == 1 ? "is" : "are"
|
602
|
+
end
|
603
|
+
(prefix ? "#{prefix} #{main}" : main.to_s)
|
604
|
+
else
|
605
|
+
key = summary.kind_of?(String) ? summary : "default"
|
606
|
+
default = c == 1 ? "There is 1 #{label}" : "There are #{c} #{label}"
|
607
|
+
t "tags.count.#{key}", {:count=>c, :label=>label, :default=>default}.merge(attributes)
|
553
608
|
end
|
554
|
-
|
555
|
-
(prefix ? "#{prefix} #{main}" : main.to_s)
|
556
|
-
|
557
609
|
end
|
558
610
|
%></span></def>
|
559
611
|
|
560
612
|
|
561
|
-
<!-- Renders a `<link rel="Stylesheet" type="text/css">` to include the default stylesheet for the selected theme (select with `<set-theme>`). Included in the default pages.
|
613
|
+
<!-- Renders a `<link rel="Stylesheet" type="text/css">` to include the default stylesheet for the selected theme (select with `<set-theme>`). Included in the default pages.
|
562
614
|
-->
|
563
615
|
<def tag="theme-stylesheet" attrs="name">
|
564
616
|
<% name ||= Hobo.current_theme -%>
|
@@ -576,28 +628,144 @@ The context should be a user object. If `this == current_user` the "you" form is
|
|
576
628
|
- `<you are/> now an admin` -> "you are now an admin" or "Jim is now an admin"
|
577
629
|
- `<you do/>n't want to go there` -> "you don't want to go there" or "Jim doesn't want to go there"
|
578
630
|
|
631
|
+
The tag is also localized in the namespaces "tags.you.current_user" and "tags.you.other_user".
|
632
|
+
Each namespace can contain the legacy keys "have", "are", "do" used for the respective attributes,
|
633
|
+
and "nothing" used when no attribute is passed. But you can also use your own keys, providing
|
634
|
+
that you add the keys in the correct namespaces.
|
635
|
+
|
636
|
+
### Examples
|
637
|
+
|
638
|
+
it:
|
639
|
+
tags:
|
640
|
+
you:
|
641
|
+
current_user:
|
642
|
+
nothing: "Tu"
|
643
|
+
have: "Hai"
|
644
|
+
are: "sei"
|
645
|
+
can: "Puoi"
|
646
|
+
other_user:
|
647
|
+
nothing: "{{name}}"
|
648
|
+
have: "{{name}} ha"
|
649
|
+
are: "{{name}} è"
|
650
|
+
can: "{{name}} può"
|
651
|
+
|
652
|
+
- `<you have/> un nuovo messaggio.` -> "Hai un nuovo messaggio." or "Jim ha un nuovo messaggio."
|
653
|
+
- `Adesso <you are/> amministratore.` -> "Adesso sei amministratore." or "Adesso Jim è amministratore."
|
654
|
+
- `<you can/> scrivere.` -> "Puoi scrivere." or "Jim può scrivere."
|
655
|
+
|
656
|
+
(note: :name is added by default as an interpolable variable)
|
657
|
+
|
579
658
|
### Attributes
|
580
659
|
|
581
|
-
-
|
582
|
-
|
583
|
-
-->
|
584
|
-
<def tag="you" attrs="have, are, do, titleize"><if test="&this == current_user"><%= "#{titleize ? 'Y' : 'y'}ou#{' have' if have}#{' are' if are}#{' do' if do_}" %></if><else><do param="default"><name/><%= "#{' has' if have}#{' is' if are}#{' does' if do_}" %></do></else></def>
|
660
|
+
- capitalize: the first letter of the resulting sentence will be capitalized
|
585
661
|
|
586
|
-
<!-- Equivalent to `<you titleize/>`. Yes it's an abuse of Ruby naming conventions, but it's so cute : ) -->
|
587
|
-
<def tag="You"><you merge titleize/></def>
|
588
662
|
|
589
|
-
|
590
|
-
<def tag="your">
|
591
|
-
<if test="&this == current_user">your</if>
|
592
|
-
<else><do param="default"><%= n = name; n.ends_with?('s') ? "#{n}'" : "#{n}'s" %></do></else>
|
593
|
-
</def>
|
663
|
+
### Additional Notes
|
594
664
|
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
665
|
+
The "titleize" attribute is deprecated: use "capitalize" instead.
|
666
|
+
|
667
|
+
-->
|
668
|
+
<def tag="you" attrs="titleize, capitalize">
|
669
|
+
<% Rails.logger.warn "'titleize' is a deprecated attribute of the 'you' tag. Please, use 'capitalize' instead." -%>
|
670
|
+
<% raise ArgumentError, "You can add only one attribute-key to the 'you' tag." if attributes.size > 1 -%>
|
671
|
+
<% k = case
|
672
|
+
when attributes[:have] then 'have'
|
673
|
+
when attributes[:are] then 'are'
|
674
|
+
when attributes[:do] then 'do'
|
675
|
+
end -%>
|
676
|
+
<if test="&this == current_user">
|
677
|
+
<%= s = t("tags.you.current_user.#{k || attributes.keys.first || 'default'}",:default=>"you #{k}")
|
678
|
+
(titleize||capitalize) ? s.sub(/^./){|c| c.upcase} : s %>
|
679
|
+
</if>
|
680
|
+
<else>
|
681
|
+
<do param="default">
|
682
|
+
<%= s = t("tags.you.other_user.#{k || attributes.keys.first || 'default'}", :name=>this.name,
|
683
|
+
:default=>"#{this.name} #{'has' if attributes[:have]}#{'is' if attributes[:are]}#{'does' if attributes[:do]}")
|
684
|
+
(titleize||capitalize) ? s.sub(/^./){|c| c.upcase} : s %>
|
685
|
+
</do>
|
686
|
+
</else>
|
599
687
|
</def>
|
600
688
|
|
689
|
+
<!-- Equivalent to `<you capitalize/>`-->
|
690
|
+
<def tag="You"><you merge capitalize/></def>
|
691
|
+
|
692
|
+
<!-- Similar to `<you>`, but renders "Your" or "Fred's" or equivalent localized strings
|
693
|
+
|
694
|
+
### Attributes
|
695
|
+
|
696
|
+
- capitalize: the first letter of the resulting sentence will be capitalized
|
697
|
+
- count: used in pluralization. If omitted it will be set to 1.
|
698
|
+
- key: used to lookup the translation in the locale file. It allows 3 different options:
|
699
|
+
- single key like 'message': simple translation in 'tags.your.message.current_user'
|
700
|
+
or 'tags.your.message.other_user'
|
701
|
+
- composite key like 'any.namespace.message': translation as for the previous case, but it will
|
702
|
+
translate also the 'any.namespace.message' and will interpolate the variable <key> (in this case :message)
|
703
|
+
in the translation
|
704
|
+
- when key is omitted it will be set to "default" and will do the translation with that key.
|
705
|
+
Pass other meaningful attributes to achieve a dynamic usage
|
706
|
+
- any other attribute passed to the tag will be used as a variable for interpolation
|
707
|
+
|
708
|
+
Notes
|
709
|
+
|
710
|
+
- The :name variable is added by default as an interpolable variable
|
711
|
+
- If no translation is found an automatic (only english) default is generated:
|
712
|
+
the Your/Jim's string, joined to the tag content.
|
713
|
+
If you pass an explicit 'default' attribute you will override the automatic default.
|
714
|
+
|
715
|
+
|
716
|
+
### Examples
|
717
|
+
|
718
|
+
it:
|
719
|
+
tags:
|
720
|
+
your:
|
721
|
+
message:
|
722
|
+
current_user:
|
723
|
+
one: "Tuo Messaggio"
|
724
|
+
other: "Tuoi Messaggi"
|
725
|
+
other_user:
|
726
|
+
one: "Messaggio di {{name}}"
|
727
|
+
other: "Messaggi di {{name}
|
728
|
+
entry:
|
729
|
+
current_user:
|
730
|
+
one: "Tua {{entry}}"
|
731
|
+
other: "Tue {{entry}}"
|
732
|
+
other_user: "{{entry}} di {{name}}"
|
733
|
+
|
734
|
+
- `<your key="message" count=>"&messages.count"/>`
|
735
|
+
-> count => 1 -> "Tuo Messaggio" or "Messaggio di Jim"
|
736
|
+
-> count => 5 -> "Tuoi Messaggi" or "Messaggi di Jim"
|
737
|
+
|
738
|
+
- `<your key="activerecord.models.entry" count=>"&this.entries.count"/>`
|
739
|
+
-> count => 1 -> "Tua Entrata" or "Entrata di Jim"
|
740
|
+
-> count => 5 -> "Tue Entrate" or "Entrate di Jim"
|
741
|
+
|
742
|
+
- `<your>Posts</your>` -> "your Posts" or "Jim's Posts"
|
743
|
+
-->
|
744
|
+
|
745
|
+
<def tag="your" attrs="key, capitalize"><%=
|
746
|
+
key ||= 'default'
|
747
|
+
# prepare symbolized attributes for merging
|
748
|
+
attrs = {}
|
749
|
+
attributes.each_pair{|k,v| attrs[k.to_sym] = v}
|
750
|
+
d = "#{your_default} #{all_parameters.default}"
|
751
|
+
options = {:default=>[d], :count=>(attrs[:count]||1), :name=>this.name}
|
752
|
+
your_key = key.split('.').last
|
753
|
+
unless key.eql?(your_key) || attrs.has_key?(your_key.to_sym)
|
754
|
+
options[your_key.to_sym] = t(key, :count=>options[:count], :default=>your_key.titleize)
|
755
|
+
end
|
756
|
+
s = if this == current_user
|
757
|
+
options[:default].unshift :"tags.your.default.current_user"
|
758
|
+
t("tags.your.#{your_key}.current_user", options.merge(attrs))
|
759
|
+
else
|
760
|
+
options[:default].unshift :"tags.your.default.other_user"
|
761
|
+
t("tags.your.#{your_key}.other_user", options.merge(attrs))
|
762
|
+
end
|
763
|
+
capitalize ? s.sub(/^./){|c| c.upcase} : s
|
764
|
+
%></def>
|
765
|
+
|
766
|
+
<!-- Equivalent to `<your ... capitalize/>`-->
|
767
|
+
<def tag="Your"><your merge capitalize/></def>
|
768
|
+
|
601
769
|
<!-- Deprecated. It's harder than you think to do this (e.g. an umbrealla, an user)
|
602
770
|
-->
|
603
771
|
<def tag="a-or-an" attrs="word"><%=
|
@@ -617,10 +785,10 @@ The context should be a user object. If `this == current_user` the "you" form is
|
|
617
785
|
|
618
786
|
<!-- Development mode only - a menu to change the `current_user` -->
|
619
787
|
<def tag="dev-user-changer">
|
620
|
-
<set user="&Hobo::
|
621
|
-
<select-menu if="&user &&
|
622
|
-
first-option="#{
|
623
|
-
onchange="location.href = '#{dev_support_path}
|
788
|
+
<set user="&Hobo::Model::UserBase.default_user_model"/>
|
789
|
+
<select-menu if="&user && Rails.env.development?"
|
790
|
+
first-option="#{t('hobo.dev_user_changer.guest', {:default=>'Guest'})}" options="&user.all(:limit => 30).*.login"
|
791
|
+
onchange="location.href = '#{dev_support_path :action=>:set_current_user}?login=' + encodeURIComponent(this.options[this.selectedIndex].value)"
|
624
792
|
selected="#{current_user.login}"
|
625
793
|
class="dev-user-changer"
|
626
794
|
merge-attrs/>
|