idioma 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +91 -0
- data/Rakefile +28 -0
- data/app/assets/javascripts/idioma/application.js +15 -0
- data/app/assets/javascripts/idioma/phrases.js.coffee +35 -0
- data/app/assets/stylesheets/idioma/application.css.scss +26 -0
- data/app/assets/stylesheets/idioma/forms.css.scss +19 -0
- data/app/assets/stylesheets/idioma/phrases.css +4 -0
- data/app/controllers/idioma/application_controller.rb +4 -0
- data/app/controllers/idioma/phrases_controller.rb +96 -0
- data/app/helpers/idioma/application_helper.rb +4 -0
- data/app/helpers/idioma/phrases_helper.rb +4 -0
- data/app/models/idioma/phrase.rb +115 -0
- data/app/models/idioma/phrase_exporter.rb +69 -0
- data/app/models/idioma/phrase_extractor.rb +49 -0
- data/app/models/idioma/phrase_importer.rb +50 -0
- data/app/models/idioma/redis_backend.rb +22 -0
- data/app/views/idioma/phrases/index.html.haml +45 -0
- data/app/views/layouts/idioma/application.html.haml +22 -0
- data/config/locales/idioma.en.yml +20 -0
- data/config/routes.rb +4 -0
- data/db/migrate/20140709015052_create_idioma_phrases.rb +14 -0
- data/lib/concerns/models/date_flag.rb +96 -0
- data/lib/idioma/engine.rb +27 -0
- data/lib/idioma/version.rb +3 -0
- data/lib/idioma.rb +23 -0
- data/lib/tasks/idioma_tasks.rake +15 -0
- data/lib/templates/erb/scaffold/_form.html.erb +13 -0
- data/spec/controllers/phrases_controller_spec.rb +91 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config/application.rb +25 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +28 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +83 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/i18n.rb +4 -0
- data/spec/dummy/config/initializers/idioma.rb +9 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/migrate/20141115171836_create_idioma_phrases.idioma.rb +15 -0
- data/spec/dummy/db/schema.rb +30 -0
- data/spec/dummy/log/development.log +25637 -0
- data/spec/dummy/log/test.log +4291 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/0a79a4ff6e73052b217cd977d4b50fdc54118d68/_bootstrap-sprockets.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/0a79a4ff6e73052b217cd977d4b50fdc54118d68/_bootstrap.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_alerts.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_background-variant.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_border-radius.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_buttons.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_center-block.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_clearfix.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_forms.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_gradients.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_grid-framework.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_grid.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_hide-text.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_image.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_labels.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_list-group.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_nav-divider.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_nav-vertical-align.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_opacity.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_pagination.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_panels.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_progress-bar.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_reset-filter.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_resize.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_responsive-visibility.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_size.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_tab-focus.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_table-row.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_text-emphasis.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_text-overflow.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/388135616c2e0e4a55abea5d6089cd23176cca81/_vendor-prefixes.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_alerts.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_background-variant.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_border-radius.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_buttons.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_center-block.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_clearfix.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_forms.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_gradients.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_grid-framework.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_grid.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_hide-text.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_image.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_labels.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_list-group.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_nav-divider.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_nav-vertical-align.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_opacity.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_pagination.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_panels.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_progress-bar.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_reset-filter.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_resize.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_responsive-visibility.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_size.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_tab-focus.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_table-row.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_text-emphasis.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_text-overflow.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/6d2c3dd352078ee620f88d0e68cd2a546af6caa9/_vendor-prefixes.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a3c1058d9af83b2a8b1bfae5d618b8a18753385f/_bootstrap-sprockets.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a3c1058d9af83b2a8b1bfae5d618b8a18753385f/_bootstrap.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_alerts.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_badges.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_breadcrumbs.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_button-groups.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_buttons.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_carousel.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_close.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_code.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_component-animations.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_dropdowns.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_forms.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_glyphicons.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_grid.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_input-groups.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_jumbotron.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_labels.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_list-group.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_media.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_mixins.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_modals.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_navbar.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_navs.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_normalize.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_pager.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_pagination.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_panels.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_popovers.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_print.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_progress-bars.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_responsive-embed.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_responsive-utilities.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_scaffolding.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_tables.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_thumbnails.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_tooltip.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_type.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_utilities.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_variables.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/a7efb1bfb1ea736b4b985c80527151a3e8b6dbc6/_wells.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/d940cd7e88bf0a9500208e10220e6b529d01020b/application.css.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/d940cd7e88bf0a9500208e10220e6b529d01020b/forms.css.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_alerts.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_badges.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_breadcrumbs.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_button-groups.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_buttons.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_carousel.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_close.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_code.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_component-animations.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_dropdowns.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_forms.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_glyphicons.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_grid.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_input-groups.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_jumbotron.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_labels.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_list-group.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_media.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_mixins.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_modals.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_navbar.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_navs.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_normalize.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_pager.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_pagination.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_panels.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_popovers.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_print.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_progress-bars.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_responsive-embed.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_responsive-utilities.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_scaffolding.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_tables.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_thumbnails.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_tooltip.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_type.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_utilities.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_variables.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/ea7b58bf4bbb3d8d5abf667eec7914942f653de6/_wells.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/02ecd6370f91c7b9aa00319b7b66ca57 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/034fda66e03e8dcfacf72397fb1616fb +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/0372d3378d1aec4dd7f546428d9d84df +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/071b598f6568db8d75333d67e6a54477 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/0faf8e82aa4c81c82c3d5efd58fcaae2 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/1665127ceea38e019fda9859305342a7 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/16b4a10fdb8214557970232c41d57362 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/1750899b365166d7cfff321fe7fa7acd +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/17e0784a695845bd1a32dd1346c280ea +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/1ad97a1fb78577c298b407d3d2cc4226 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/1c146cfb664a6770a3d20305f8baaee3 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/1d53471c5ad320073dda367e45390e1a +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/1f6b42e6726c8b498066fc910a16e643 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/25a65c717fc9c64ba1aba14d1c14ffee +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/291cfa25c65c3163a5815d67b5f62756 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2acbd5c6f7047cd0e95f86968fd19f46 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2e4f3bcd559a961bc58e2a0e84792662 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2f31bab0beabd5a3f5c34b4e907a34fc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/306a635124154ffdea9b8e8ce8b61410 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/30e642c26825645592d13dd299e19a65 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3312b404b988f9a8763bd1c06b9952ef +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3487ff606d58ba5df51a1117dba8c84b +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/357d6ae318d42fc558676b425c1a9e78 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/361cc4bdb4a3f33a6ba7e9a7db1a5407 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3636dd32d14102a55225b245bd2a6489 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/36874c0716e0da5db2dde7cf47dec6ca +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/39ce7471b9ff1c273b4f1518b5aba8f0 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3b25a99aa1b8d0f87755ebd53f3d7fc6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3bf04cff80d6513190387eea44e4589f +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3c284cbc7d309735cbebcaddf4467d71 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3d067ab624734ad0663d1425c5b201c1 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3fb41299c66c3e363e841ca3d76b11b7 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/4063ddd81171d5b6dc967ca64faeca75 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/40ca1415d6ca19cdf937bbc542925af9 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/40e3a16192cb5bd3559b3abe6b31cefe +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/43f257974098a37cabc9a61314b816f5 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/44657b24ddb307d1e7f85ad2ecca2e10 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/458ca3a8c2f4224a08e724716a2f17d4 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/4a368dccbd67682ba64048d4b24fd8a6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/4a85c925086e64caf1d1b700d916bdbd +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/4ce8718297a50cd3d658b5952cd8c220 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/510c6fd27db7dfbaf0a0b0875e1a472c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/52601bfc1fdc6967ffc898526bb67c48 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/52f63d83d0a7b86318e8de59538598ce +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/5369fbbcf397cc9d96948fe373705d13 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/56435206e505c649b556d17094d68fda +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/5814911eaed8f6e6be8c46d6b9cb880f +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/58f4e4ba656d78cf623d22cca4e118d9 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/5d2ca5f96ec23ecb6926eb3732d45e40 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/650130979c39b20be8a1c9af85b76638 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6a9bec079f93d94c0dbf4b7faa1441ad +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6c75734197a9efc5a8a3a6ca1064eb41 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6f388bb30dc94599b503d0d9091f1d8a +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6f88ef16a3db4dfcde35acff34596af9 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6f894580ff1180ef27e44fb54bfec225 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6f9d821dc32360a03e328a188908175f +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/7002ce8d64dafbc1a536eeeb902218c0 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/7005283a4d4bbbdee421e3479dc12cef +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/7311218619b974306177cebe229dc84c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/744470be6e2c66f767dd3796ce78f559 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/75e87583a132b975027118095bf4818f +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/764d58940328aaefb24a04bef44b3789 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/76736f185d75c28fcb1a476ae52cf30e +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/772600c69b884a0036fb15de213d3232 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/7a3ccc02bfad9d04783b020d3dcdb67f +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/7da54db8bdd56cd00dc338448b263424 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/7f402d16975bdcfc442e9cef98821840 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/7f992b68655a9d27c89d97eeeaae5cff +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/812a0d810b679dbb7f5d512beef887c8 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/81cfdb55475e7b7a5a63ffe9c204673c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/81fce3ac36b10e033b9264e39a76d90a +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/83dafa375dd3513360fd7b4553f44113 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/846430db48a99b44ec1b08022d0276ad +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/8747b295bb7c63b1388aef97cfb67b3c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/87bf4781cd1e8b52a4b8fc2c0e379531 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/8960bbc70a2914b7ed8e6f7b5b04359f +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/8abcaf5a11cddb7b0c2aa424bd1e3b80 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/90edf8db23ea1dbf263e6391e93a483d +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/92871f270f3bebaf37c07d62016a3d7e +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/933dfcd36b972a52fa603f5234bd1e7e +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/960b52015983bd58ede5592a759c08fb +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/96eb906f063e4ce8718416772a28ddda +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/97c07e644cabf01abcec894d4e69d985 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/9d2af4036fcf352fd6695966ba8e0006 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/a011ecbdccaea9b25d06cedffa60f15b +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/a200c1f26bc11623541b221d0b819a31 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/a3900259c72f7f6917024284b8bdc4fb +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/a45d05646c5fc237f0a7419ba456eaaa +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/a4819b17d0802ac0d8d7e2a9d1832752 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/a57c75e1396ec82ae78589a9ae6b3861 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/a5d6adcfd6cbc7beef744d02302d0a8c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/a6e5e94828ebb7680a0a1499dda39e2c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/ada1d0f8bc5368b25d6fbaa8a95b4ef8 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/ada35950e2733da1d227585deb4a09fd +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/aefe71c7ac3edd29fbbb6a3e4bfe84a4 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/b0376faf689d528b625a5a88ef0dcc7a +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/b7e39ee40edb822dde438cae9f5b0987 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/b8c774f83a302c891103bdf82662bc8d +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/bb86516784ddda57801c5b5ca185e838 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/be81012acaf20ecb9f67c32dbc2ee5ae +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/bfa847822a8d7778ab5f8b469491b114 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c7e523ec10215d71cb5d98fe9e069b35 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c82292a064ec438357e22805eee89191 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c843a7a53cf4a5dc94dfea6a59f04e4f +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d05de76ba0f58b49a47dea63d2a5b4a6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d5022437eeb42f08dd710ee8f240de2a +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d71a839bca3a6881f8b7b42b7f05bda6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d976a7c91926f70a3e80c2603de3bf69 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/dd677fcb17536b3f6c2bf936f571a02e +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/df9a7d2c532e121a104d5b63b4441b2d +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/e29bdfdcad985cd8d26e1d31a09f00b1 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/e46bf23d379db0e7483b2ccc0fbff9f3 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/e5fa939c3fa26ae0df54d40f316bec75 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/e6f47dfc8b9542ee9c6f54b1ecfde664 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/e75d8f8a9ec139a10086a83dca74e9b3 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/eb29baddef1d85815159f3d1089e3be4 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/efa76e374b3ab82bde4b35f9d76d9caf +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f1262794e42011b8c57f36f71b9815a0 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f5268ce26d4948c182f520c4df83b261 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f6f7145113c3cd4e160e3d39f7f1f56b +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f757aee56e52254e2fb14b4f6424c937 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/fbf4527e3604500e4c3521c4fd2deaf6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/ff4769a8564990f599f4e977ccd8e661 +0 -0
- data/spec/dummy/tmp/pids/server.pid +1 -0
- data/spec/dummy/tmp/restart.txt +0 -0
- data/spec/factories/phrase.rb +8 -0
- data/spec/models/phrase_exporter_spec.rb +38 -0
- data/spec/models/phrase_extractor_spec.rb +53 -0
- data/spec/models/phrase_importer_spec.rb +30 -0
- data/spec/models/phrase_spec.rb +80 -0
- data/spec/spec_helper.rb +23 -0
- metadata +851 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4297d3391e67e66042c2a6572edf9e8928bdd39a
|
4
|
+
data.tar.gz: 3d9c1f1a8c2efb1b012a008a7ee12fb145543af5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3c071cda64b47acf5fbb7653edb39c5bebe920a823dee0b28847120a5c1c584fc525ea2f1323d09349b888de58317d5b09bfa8a9a2a5547547b634b1942a3413
|
7
|
+
data.tar.gz: 449f8cd93ddc4c1fac4a435d0b189ed9afe3f496c73d18b93957326f47bcc6cf6dbab74ef37fecb3bfb4542c33269b311589b98601a7064bbd5e575f1a8fa175
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2014 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
# Idioma
|
2
|
+
|
3
|
+
Idioma is a Ruby Engine to help manage the flow and editing of translations.
|
4
|
+
|
5
|
+
### Current Features
|
6
|
+
* Imports translations into database from the config yaml files.
|
7
|
+
* Interface for managing translations.
|
8
|
+
* Duplicate translations from one locale to other locales.
|
9
|
+
* DB changes will be persisted to Redis I18n backend store if supplied.
|
10
|
+
* Exports translations from DB into CSV and YAML formats.
|
11
|
+
|
12
|
+
### Pending Features
|
13
|
+
* Import translations from CSV into DB.
|
14
|
+
* Stats on each locale, giving percentage of translated/missing.
|
15
|
+
* Test persisting to Redis using https://github.com/guilleiguaran/fakeredis
|
16
|
+
* Improve interface by converting into SPA with Angular.
|
17
|
+
|
18
|
+
### Starting
|
19
|
+
Add it to your gemfile.
|
20
|
+
```ruby
|
21
|
+
gem 'idioma'
|
22
|
+
```
|
23
|
+
|
24
|
+
Mount it in your config/routes.rb.
|
25
|
+
```ruby
|
26
|
+
# config/routes.rb
|
27
|
+
MyApp::Application.routes.draw do
|
28
|
+
mount Idioma::Engine => "/idioma"
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
### Security
|
33
|
+
You can secure access to the Idioma interface by using [route constraints](http://guides.rubyonrails.org/routing.html#request-based-constraints).
|
34
|
+
|
35
|
+
Example 1 by IP address.
|
36
|
+
```ruby
|
37
|
+
# config/routes.rb
|
38
|
+
idioma_constraint = lambda { |request| request.remote_ip == '127.0.0.1' }
|
39
|
+
constraints idioma_constraint do
|
40
|
+
mount Idioma::Engine => "/idioma"
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
Example 2 by using Devise or another warden based authentication system.
|
45
|
+
```ruby
|
46
|
+
# config/routes.rb
|
47
|
+
idioma_constraint = lambda do |request|
|
48
|
+
current_user = request.env['warden'].user
|
49
|
+
current_user.present? && current_user.respond_to?(:is_admin?) && current_user.is_admin?
|
50
|
+
end
|
51
|
+
|
52
|
+
constraints idioma_constraint do
|
53
|
+
mount Idioma::Engine => "/idioma"
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
### Configuration
|
58
|
+
Setting | Default | Description
|
59
|
+
------- | ------- | -----------
|
60
|
+
default_locale | :en | Used for showing the default translation (for translators to translate from) for a given phrase
|
61
|
+
locales | [:en] | Idioma will only import translations of locales in this list... ignoring the rest
|
62
|
+
ignore_keys | ["ransack", "simple_form"] | Gems sometimes bring their own phrases that you don't actually need translated
|
63
|
+
redis_backend | nil | Should be an I18n backend of a Redis store.
|
64
|
+
|
65
|
+
### Setup
|
66
|
+
Import the migrations into your application
|
67
|
+
```
|
68
|
+
rake idioma:install:migrations
|
69
|
+
```
|
70
|
+
|
71
|
+
To populate the idioma_phrases table with translations from your locales/yaml files.
|
72
|
+
```
|
73
|
+
rake idioma:import_from_extraction
|
74
|
+
```
|
75
|
+
|
76
|
+
To duplicate all translations from a locale to a new locale (as untranslated).
|
77
|
+
```
|
78
|
+
rake idioma:duplicate_for_locales base_locale=en new_locale=es
|
79
|
+
```
|
80
|
+
|
81
|
+
### Example
|
82
|
+
```ruby
|
83
|
+
$redis = Redis.new(:host => 'localhost', :port => 6379)
|
84
|
+
I18n.backend = I18n::Backend::KeyValue.new($redis)
|
85
|
+
|
86
|
+
Idioma.configure do |configure|
|
87
|
+
configure.default_locale = :en
|
88
|
+
configure.locales = [:en, :es, :fr]
|
89
|
+
configure.redis_backend = I18n.backend
|
90
|
+
end
|
91
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Idioma'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
Bundler::GemHelper.install_tasks
|
21
|
+
|
22
|
+
require 'rspec/core'
|
23
|
+
require 'rspec/core/rake_task'
|
24
|
+
|
25
|
+
desc "Run all specs in spec directory (excluding plugin specs)"
|
26
|
+
RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
|
27
|
+
|
28
|
+
task :default => :spec
|
@@ -0,0 +1,15 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
14
|
+
//= require jquery
|
15
|
+
//= require bootstrap-sprockets
|
@@ -0,0 +1,35 @@
|
|
1
|
+
window.InlinePhraseUpdater = class InlinePhraseUpdater
|
2
|
+
constructor: () ->
|
3
|
+
# attributes
|
4
|
+
@phraseInputs = $(".i18n_value")
|
5
|
+
|
6
|
+
# events
|
7
|
+
@phraseInputs.on "focus", (e) => @setOriginalValue(e)
|
8
|
+
@phraseInputs.on "blur", (e) => @updateIfChanged(e)
|
9
|
+
|
10
|
+
# init
|
11
|
+
|
12
|
+
setOriginalValue: (e) =>
|
13
|
+
phraseInput = $(e.target)
|
14
|
+
phraseInput.data("original", phraseInput.val())
|
15
|
+
|
16
|
+
updateIfChanged: (e) =>
|
17
|
+
phraseInput = $(e.target)
|
18
|
+
if phraseInput.data("original") != phraseInput.val()
|
19
|
+
@updateStatus(phraseInput, "status-working")
|
20
|
+
$.ajax(
|
21
|
+
type: "PUT"
|
22
|
+
url: phraseInput.data("url")
|
23
|
+
dataType: "json"
|
24
|
+
data:
|
25
|
+
phrase:
|
26
|
+
i18n_value: phraseInput.val()
|
27
|
+
).done((data) =>
|
28
|
+
@updateStatus(phraseInput, "status-success")
|
29
|
+
).fail((data) =>
|
30
|
+
@updateStatus(phraseInput, "status-error")
|
31
|
+
)
|
32
|
+
|
33
|
+
updateStatus: (input, status) ->
|
34
|
+
input.removeClass("status-success").removeClass("status-error").removeClass("status-working")
|
35
|
+
input.addClass(status)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
16
|
+
@import "bootstrap-sprockets";
|
17
|
+
@import "bootstrap";
|
18
|
+
|
19
|
+
body {
|
20
|
+
padding-top: 50px;
|
21
|
+
}
|
22
|
+
|
23
|
+
.highlight {
|
24
|
+
padding: 10px;
|
25
|
+
background-color: #f8f8f8;
|
26
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
.search {
|
2
|
+
.form-group {
|
3
|
+
padding-right: 10px;
|
4
|
+
}
|
5
|
+
|
6
|
+
label {
|
7
|
+
margin-right: 10px;
|
8
|
+
}
|
9
|
+
}
|
10
|
+
|
11
|
+
.status-working {
|
12
|
+
border-color: yellow !important;
|
13
|
+
}
|
14
|
+
.status-success {
|
15
|
+
border-color: green !important;
|
16
|
+
}
|
17
|
+
.status-error {
|
18
|
+
border-color: red !important;
|
19
|
+
}
|
@@ -0,0 +1,96 @@
|
|
1
|
+
#require_dependency "idioma/application_controller"
|
2
|
+
|
3
|
+
module Idioma
|
4
|
+
class PhrasesController < ApplicationController
|
5
|
+
before_action :set_phrase, only: [:edit, :update, :show]
|
6
|
+
|
7
|
+
# GET /phrases
|
8
|
+
def index
|
9
|
+
params[:locale] ||= I18n.default_locale
|
10
|
+
scope = Phrase.where(locale: params[:locale])
|
11
|
+
|
12
|
+
if params[:q].present?
|
13
|
+
scope = scope.where("i18n_key ilike ? OR i18n_value ilike ?", "%#{params[:q]}%", "%#{params[:q]}%")
|
14
|
+
end
|
15
|
+
|
16
|
+
respond_to do |format|
|
17
|
+
format.html {
|
18
|
+
@phrases = scope.paginate(:page => params[:page])
|
19
|
+
}
|
20
|
+
format.csv {
|
21
|
+
render text: PhraseExporter.to_csv(scope)
|
22
|
+
}
|
23
|
+
format.yaml {
|
24
|
+
render text: PhraseExporter.to_yaml(scope)
|
25
|
+
}
|
26
|
+
format.json {
|
27
|
+
@phrases = scope.paginate(:page => params[:page])
|
28
|
+
render json: {
|
29
|
+
meta: {
|
30
|
+
pagination: {
|
31
|
+
current_page: @phrases.current_page,
|
32
|
+
per_page: @phrases.per_page,
|
33
|
+
total_entries: @phrases.total_entries
|
34
|
+
}
|
35
|
+
},
|
36
|
+
phrases: @phrases
|
37
|
+
}
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
# GET /phrases/1
|
44
|
+
def show
|
45
|
+
respond_to do |format|
|
46
|
+
format.json {
|
47
|
+
render json: @phrase
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# PATCH/PUT /phrases/1
|
53
|
+
def update
|
54
|
+
result = @phrase.update_and_update_backend(phrase_params)
|
55
|
+
respond_to do |format|
|
56
|
+
format.html {
|
57
|
+
if result
|
58
|
+
redirect_to [:edit, @phrase], flash: {success: t('idioma.record_updated')}
|
59
|
+
else
|
60
|
+
render :edit
|
61
|
+
end
|
62
|
+
}
|
63
|
+
format.json {
|
64
|
+
if result
|
65
|
+
render json: @phrase
|
66
|
+
else
|
67
|
+
render json: {
|
68
|
+
errors: @phrase.errors.messages
|
69
|
+
}.merge(@phrase.attributes),
|
70
|
+
status: :bad_request
|
71
|
+
end
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
# Use callbacks to share common setup or constraints between actions.
|
79
|
+
def set_phrase
|
80
|
+
@phrase = Phrase.find(params[:id])
|
81
|
+
rescue ActiveRecord::RecordNotFound
|
82
|
+
respond_to do |format|
|
83
|
+
format.json { render json: {}.to_json, status: :not_found }
|
84
|
+
format.html {
|
85
|
+
flash[:error] = t('idioma.record_not_found')
|
86
|
+
redirect_to phrases_path
|
87
|
+
}
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Only allow a trusted parameter "white list" through.
|
92
|
+
def phrase_params
|
93
|
+
params.require(:phrase).permit(:locale, :i18n_key, :i18n_value, :flagged_at, :notes)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module Idioma
|
2
|
+
class Phrase < ActiveRecord::Base
|
3
|
+
|
4
|
+
# == Constants ============================================================
|
5
|
+
|
6
|
+
# == Attributes ===========================================================
|
7
|
+
|
8
|
+
# == Extensions ===========================================================
|
9
|
+
|
10
|
+
# == Relationships ========================================================
|
11
|
+
|
12
|
+
# == Validations ==========================================================
|
13
|
+
|
14
|
+
validates :locale, :i18n_key, presence: true
|
15
|
+
validates :i18n_key, uniqueness: { scope: :locale }
|
16
|
+
|
17
|
+
# == Scopes ===============================================================
|
18
|
+
|
19
|
+
scope :translated, lambda { where("translated_at is not null") }
|
20
|
+
scope :untranslated, lambda { where("translated_at is null") }
|
21
|
+
scope :missing, lambda { where("i18n_value is null") }
|
22
|
+
|
23
|
+
# == Callbacks ============================================================
|
24
|
+
|
25
|
+
before_validation :strip_values
|
26
|
+
|
27
|
+
# == Class Methods ========================================================
|
28
|
+
|
29
|
+
# Given a base locale, duplicate all phrases to a set of other locales
|
30
|
+
#
|
31
|
+
# @param [Symbol] The base locale
|
32
|
+
# @param [Array] An array of other locales
|
33
|
+
def self.duplicate_for_locales(base_locale, locales)
|
34
|
+
locales = [locales] unless locales.class == Array
|
35
|
+
where(locale: base_locale).find_each do |base_phrase|
|
36
|
+
locales.each do |locale|
|
37
|
+
unless where(locale: locale, i18n_key: base_phrase.i18n_key).exists?
|
38
|
+
phrase = Phrase.create!({
|
39
|
+
locale: locale,
|
40
|
+
i18n_key: base_phrase.i18n_key
|
41
|
+
})
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Take what's in the database and prime the i18n backend store (Redis)
|
48
|
+
def self.prime_backend
|
49
|
+
find_each do |phrase|
|
50
|
+
phrase.update_backend
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# == Instance Methods =====================================================
|
55
|
+
|
56
|
+
# Update the record and then push those changes to the i18n backend
|
57
|
+
#
|
58
|
+
# @param [Hash] The Phrase attributes to update
|
59
|
+
# @return [Boolean] Whether the update was successful
|
60
|
+
def update_and_update_backend(params = {})
|
61
|
+
self.translated_at = Time.zone.now if self.untranslated?
|
62
|
+
|
63
|
+
result = self.update(params)
|
64
|
+
if result
|
65
|
+
self.update_backend
|
66
|
+
end
|
67
|
+
result
|
68
|
+
end
|
69
|
+
|
70
|
+
# Save and push the changes to the i18n backend
|
71
|
+
#
|
72
|
+
# @param [Hash] The Phrase attributes to save
|
73
|
+
# @return [Boolean] Whether the save was successful
|
74
|
+
def save_and_update_backend(params = {})
|
75
|
+
result = self.save(params)
|
76
|
+
if result
|
77
|
+
self.update_backend
|
78
|
+
end
|
79
|
+
result
|
80
|
+
end
|
81
|
+
|
82
|
+
# Will update the i18n backend if it has been configured
|
83
|
+
def update_backend
|
84
|
+
if Idioma.configuration.redis_backend
|
85
|
+
if i18n_value.present?
|
86
|
+
Idioma::RedisBackend.update_phrase(self)
|
87
|
+
else
|
88
|
+
Idioma::RedisBackend.delete_phrase(self)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Is this phrase translated?
|
94
|
+
# @return [Boolean]
|
95
|
+
def translated?
|
96
|
+
translated_at.present?
|
97
|
+
end
|
98
|
+
|
99
|
+
# Is this phrase untranslated?
|
100
|
+
# @return [Boolean]
|
101
|
+
def untranslated?
|
102
|
+
!translated?
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
# Strip the values before validating the model
|
108
|
+
def strip_values
|
109
|
+
[:i18n_value].each do |field|
|
110
|
+
self.send("#{field}=", self.send(field).to_s.strip)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Idioma
|
2
|
+
class PhraseExporter
|
3
|
+
|
4
|
+
# Produce a CSV string of Phrases based on a scope
|
5
|
+
# @param [ActiveRecord::Relation] From the Phrase model
|
6
|
+
# @return [String] in CSV format
|
7
|
+
def self.to_csv(scope)
|
8
|
+
require 'csv'
|
9
|
+
CSV.generate do |csv_object|
|
10
|
+
csv_object << [
|
11
|
+
I18n.t("idioma.locale"),
|
12
|
+
I18n.t("idioma.key"),
|
13
|
+
I18n.t("idioma.value"),
|
14
|
+
I18n.t("idioma.translated")
|
15
|
+
]
|
16
|
+
scope.find_each do |phrase|
|
17
|
+
csv_object << [
|
18
|
+
phrase.locale,
|
19
|
+
phrase.i18n_key,
|
20
|
+
phrase.i18n_value,
|
21
|
+
phrase.translated_at.present? ? I18n.t('idioma.ans_yes') : I18n.t('idioma.ans_no')
|
22
|
+
]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Produce a YAML string of Phrases based on a scope
|
28
|
+
# @param [ActiveRecord::Relation] From the Phrase model
|
29
|
+
# @return [String] in YAML format
|
30
|
+
def self.to_yaml(scope)
|
31
|
+
phrases = scope.order(:locale, :i18n_key).pluck(:locale, :i18n_key, :i18n_value)
|
32
|
+
|
33
|
+
phrase_hash = phrases.each_with_object({}) do |phrase, hsh|
|
34
|
+
hsh["#{phrase[0]}.#{phrase[1]}"] = phrase[2]
|
35
|
+
end
|
36
|
+
|
37
|
+
to_nested_hash(phrase_hash).to_yaml
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# Will take a flat hash with dot notation (en.errors.invalid) keys and
|
43
|
+
# convert it to a nested hash.
|
44
|
+
#
|
45
|
+
# Example: {"en.hello" => "Hi"} becomes {"en" => {"hello" => "Hi"}}
|
46
|
+
#
|
47
|
+
# @param [Hash] Flat hash with dot notation keys
|
48
|
+
# @return [Hash] Nested hash
|
49
|
+
def self.to_nested_hash(input_hash)
|
50
|
+
input_hash.each_with_object({}) do |(key, value), hsh|
|
51
|
+
hsh.deep_merge!(dot_keys_to_hash(key.split("."), value))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Will take an array of keys and a value, and convert this into a nested
|
56
|
+
# hash.
|
57
|
+
# @param [Array] Of keys
|
58
|
+
# @param [Object] Any value
|
59
|
+
# @return [Hash] Nested hash using the keys and value
|
60
|
+
def self.dot_keys_to_hash(keys, value)
|
61
|
+
if keys.length == 1
|
62
|
+
{keys.first => value}
|
63
|
+
else
|
64
|
+
{keys.shift => dot_keys_to_hash(keys, value)}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Idioma
|
2
|
+
class PhraseExtractor
|
3
|
+
|
4
|
+
# Find all of the translations that are in the locale yaml files
|
5
|
+
# and convert them into a hash of dotted hash notation key/values
|
6
|
+
# for each locale that is found
|
7
|
+
# @return [Hash] Dotted hash notation key/value pairs
|
8
|
+
def self.extract
|
9
|
+
phrase_hashes = self.get_translations
|
10
|
+
|
11
|
+
phrase_dotted_hashes = {}
|
12
|
+
# convert each locales translations to dotted hash
|
13
|
+
phrase_hashes.each do |locale, phrase_hash|
|
14
|
+
phrase_dotted_hashes[locale] = self.to_dotted_hash(phrase_hash)
|
15
|
+
end
|
16
|
+
|
17
|
+
phrase_dotted_hashes
|
18
|
+
end
|
19
|
+
|
20
|
+
# Get translations from the i18n backend
|
21
|
+
# @param [I18n::Backend, nil] A custom I18n backend
|
22
|
+
# @return [Hash] of translations separated by locale
|
23
|
+
def self.get_translations(backend = nil)
|
24
|
+
backend = I18n::Backend::Simple.new if backend.nil?
|
25
|
+
backend.send(:init_translations)
|
26
|
+
backend.send(:translations)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Convert a nested Hash ({date: {format: {long: "YYYY-MM-DD"}}})
|
30
|
+
# to a dotted hash {"date.format.long" => "YYYY-MM-DD"}
|
31
|
+
# @param [Hash] Nested hash input
|
32
|
+
# @param [Hash, {}] An accumulator to store the result
|
33
|
+
# @param [String, nil] An accumulator for the key that gets built up
|
34
|
+
# @return [Hash] The end result after the conversion
|
35
|
+
def self.to_dotted_hash(source, accumulator = {}, namespace = nil)
|
36
|
+
prefix = "#{namespace}." if namespace
|
37
|
+
case source
|
38
|
+
when Hash
|
39
|
+
source.each do |key, value|
|
40
|
+
to_dotted_hash(value, accumulator, "#{prefix}#{key}")
|
41
|
+
end
|
42
|
+
else
|
43
|
+
accumulator[namespace] = source
|
44
|
+
end
|
45
|
+
accumulator
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Idioma
|
2
|
+
class PhraseImporter
|
3
|
+
|
4
|
+
# Import all of the locales and phrases from the extraction
|
5
|
+
# The extraction comes from Idioma::PhraseExtractor.extract
|
6
|
+
def self.import_from_extraction
|
7
|
+
phrases = Idioma::PhraseExtractor.extract
|
8
|
+
phrases.each do |locale, locale_phrases|
|
9
|
+
next unless Idioma.configuration.locales.include?(locale.to_sym)
|
10
|
+
self.import(locale, locale_phrases)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# For a given locale, impot its phrases
|
15
|
+
#
|
16
|
+
# @param [Symbol] the locale, eg. :en
|
17
|
+
# @param [Hash] a hash of phrases which are already in dot-notation
|
18
|
+
def self.import(locale, locale_phrases)
|
19
|
+
locale_phrases.each do |key, value|
|
20
|
+
next if self.ignore_key?(key)
|
21
|
+
|
22
|
+
phrase = Idioma::Phrase.find_by(locale: locale, i18n_key: key)
|
23
|
+
if !phrase
|
24
|
+
phrase = Idioma::Phrase.new({
|
25
|
+
locale: locale,
|
26
|
+
i18n_key: key,
|
27
|
+
i18n_value: value,
|
28
|
+
translated_at: Time.zone.now
|
29
|
+
})
|
30
|
+
elsif phrase.untranslated?
|
31
|
+
phrase.i18n_value = value
|
32
|
+
phrase.translated_at = Time.zone.now if value.present?
|
33
|
+
end
|
34
|
+
phrase.save_and_update_backend
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Checks to see if a given key should be ignored based on the ignore_keys array
|
39
|
+
#
|
40
|
+
# @param [String] The key to check against
|
41
|
+
# @return [Boolean] Whether to ignore this key or not
|
42
|
+
def self.ignore_key?(key)
|
43
|
+
Idioma.configuration.ignore_keys.each do |ignore_key|
|
44
|
+
return true if key.to_s.include?(ignore_key)
|
45
|
+
end
|
46
|
+
false
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Idioma
|
2
|
+
|
3
|
+
# Class for dealing with deleting and updating phrases in the i18n backend.
|
4
|
+
# This is specifically when the backend is Redis
|
5
|
+
class RedisBackend
|
6
|
+
|
7
|
+
# Delete a given Phrase from Redis
|
8
|
+
# @param [Phrase] The Phrase to delete
|
9
|
+
# @return [Boolean] Result of the del command in Redis
|
10
|
+
def self.delete_phrase(phrase)
|
11
|
+
Idioma.configuration.redis_backend.store.del("#{phrase.locale}.#{phrase.i18n_key}")
|
12
|
+
end
|
13
|
+
|
14
|
+
# Update (or create) a Phrase in Redis
|
15
|
+
# @param [Phrase] The Phrase to update or create
|
16
|
+
# @return [Boolean] Result of the store_translations command from the Redis backend (I18n::Backend)
|
17
|
+
def self.update_phrase(phrase)
|
18
|
+
Idioma.configuration.redis_backend.
|
19
|
+
store_translations(phrase.locale, {phrase.i18n_key => phrase.i18n_value}, :escape => false)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|