Giter VIP home page Giter VIP logo

translator's Introduction

Translator

Installation

For MongoDB:

Create Gemfile and run “bundle”:

gem 'mongo'
gem 'bson_ext'
gem 'translator', :git => "git://github.com/amberbit/translator.git"

Create initializer, for example config/initializers/translator.rb:

conn = Mongo::Connection.new.db("translator_test").collection("translations")
Translator.current_store = Translator::MongoStore.new(conn)
I18n.backend = Translator.setup_backend(I18n::Backend::Simple.new)

In Rails > 3.2 you should mount the translator Engine in config/routes.rb:

mount Translator::Engine => '/admin' # will provide a /admin/translations path

You might also need to override default yaml parser by adding the line to Gemfile:

gem 'yajl-ruby', require: 'yajl/json_gem'

There also appear to be problems with i18n v0.6.1 (truncated translations), so you might need to force v0.6.0:

gem 'i18n', '0.6.0'

For Redis:

Create Gemfile and run “bundle”:

gem 'redis'
gem 'translator', :git => "git://github.com/amberbit/translator.git"

Create initializer, for example config/initializers/translator.rb:

Translator.current_store = Translator::RedisStore.new(Redis.new)
I18n.backend = Translator.setup_backend(I18n::Backend::Simple.new)

Usage

Remember to restart your server after running ‘bundle’ command. Translations engine is available under localhost:3000/translations and there is *no authorization* by default.

Default values for your translations will be loaded from config/locales/*.yml and you can revert back to using them by clicking “Default” link next to translations you make.

Adding authorization

You can add custom authorization procedure, that will be executed in context of translations controller. Just append some code to your initializer.

For simple HTTP Basic authorization, you could use the following:

Translator.auth_handler = proc {
  authenticate_or_request_with_http_basic do |user_name, password|
    user_name == 'some' && password == 'user'
  end
}

Or to use with Devise and some RBAC:

Translator.auth_handler = proc {
  unless current_user && current_user.roles.include?(Role.find_by_name("admin"))
    redirect_to new_user_session_path
  end
}

Custom layout

You can use custom layout if you want. Remember to include jQuery with Rails’ UJS bindings to it, otherwise ‘Default’ link will not work, but you will be able to perform translations.

To use custom layout file (“admin.html.erb” in this example), append the following code to initializer:

Translator.layout_name = "admin"

Adding extra ‘Framework Translations’

Framework translations tab by default includes all Rails translations, skipping ActiveRecord and ActionMailer ones. Minimal approach here. But you can mark whichever keys you want as ‘Framework Translations’. Here’s the example that you could use with Spree:

spree_keys = ["activerecord.errors.messages.invalid", "activerecord.errors.messages.invalid_event", "activerecord.errors.messages.invalid_transition", "activerecord.errors.messages.taken", "activerecord.errors.messages.record_invalid", "activerecord.attributes.address.address1", "activerecord.attributes.address.address2", "activerecord.attributes.address.city", "activerecord.attributes.address.country", "activerecord.attributes.address.first_name", "activerecord.attributes.address.first_name_begins_with", "activerecord.attributes.address.last_name", "activerecord.attributes.address.last_name_begins_with", "activerecord.attributes.address.phone", "activerecord.attributes.address.state", "activerecord.attributes.address.zipcode", "activerecord.attributes.checkout.bill_address.address1", "activerecord.attributes.checkout.bill_address.city", "activerecord.attributes.checkout.bill_address.firstname", "activerecord.attributes.checkout.bill_address.lastname", "activerecord.attributes.checkout.bill_address.phone", "activerecord.attributes.checkout.bill_address.state", "activerecord.attributes.checkout.bill_address.zipcode", "activerecord.attributes.checkout.ship_address.address1", "activerecord.attributes.checkout.ship_address.city", "activerecord.attributes.checkout.ship_address.firstname", "activerecord.attributes.checkout.ship_address.lastname", "activerecord.attributes.checkout.ship_address.phone", "activerecord.attributes.checkout.ship_address.state", "activerecord.attributes.checkout.ship_address.zipcode", "activerecord.attributes.country.iso", "activerecord.attributes.country.iso3", "activerecord.attributes.country.iso_name", "activerecord.attributes.country.name", "activerecord.attributes.country.numcode", "activerecord.attributes.creditcard.cc_type", "activerecord.attributes.creditcard.month", "activerecord.attributes.creditcard.number", "activerecord.attributes.creditcard.verification_value", "activerecord.attributes.creditcard.year", "activerecord.attributes.inventory_unit.state", "activerecord.attributes.line_item.price", "activerecord.attributes.line_item.quantity", "activerecord.attributes.order.checkout_complete", "activerecord.attributes.order.ip_address", "activerecord.attributes.order.item_total", "activerecord.attributes.order.number", "activerecord.attributes.order.special_instructions", "activerecord.attributes.order.state", "activerecord.attributes.order.total", "activerecord.attributes.product.available_on", "activerecord.attributes.product.cost_price", "activerecord.attributes.product.description", "activerecord.attributes.product.master_price", "activerecord.attributes.product.name", "activerecord.attributes.product.on_hand", "activerecord.attributes.product.shipping_category", "activerecord.attributes.product.tax_category", "activerecord.attributes.product_group.name", "activerecord.attributes.product_group.product_count", "activerecord.attributes.product_group.product_scopes", "activerecord.attributes.product_group.products", "activerecord.attributes.product_group.url", "activerecord.attributes.product_scope.arguments", "activerecord.attributes.product_scope.description", "activerecord.attributes.property.name", "activerecord.attributes.property.presentation", "activerecord.attributes.prototype.name", "activerecord.attributes.return_authorization.amount", "activerecord.attributes.role.name", "activerecord.attributes.state.abbr", "activerecord.attributes.state.name", "activerecord.attributes.tax_category.description", "activerecord.attributes.tax_category.name", "activerecord.attributes.tax_rate.amount", "activerecord.attributes.taxon.name", "activerecord.attributes.taxon.permalink", "activerecord.attributes.taxon.position", "activerecord.attributes.taxonomy.name", "activerecord.attributes.user.email", "activerecord.attributes.variant.cost_price", "activerecord.attributes.variant.depth", "activerecord.attributes.variant.height", "activerecord.attributes.variant.price", "activerecord.attributes.variant.sku", "activerecord.attributes.variant.weight", "activerecord.attributes.variant.width", "activerecord.attributes.zone.description", "activerecord.attributes.zone.name", "activerecord.models.address.one", "activerecord.models.address.other", "activerecord.models.cheque_payment.one", "activerecord.models.cheque_payment.other", "activerecord.models.country.one", "activerecord.models.country.other", "activerecord.models.creditcard.one", "activerecord.models.creditcard.other", "activerecord.models.creditcard_payment.one", "activerecord.models.creditcard_payment.other", "activerecord.models.creditcard_txn.one", "activerecord.models.creditcard_txn.other", "activerecord.models.inventory_unit.one", "activerecord.models.inventory_unit.other", "activerecord.models.line_item.one", "activerecord.models.line_item.other", "activerecord.models.order.one", "activerecord.models.order.other", "activerecord.models.payment.one", "activerecord.models.payment.other", "activerecord.models.product.one", "activerecord.models.product.other", "activerecord.models.product_group.one", "activerecord.models.product_group.other", "activerecord.models.property.one", "activerecord.models.property.other", "activerecord.models.prototype.one", "activerecord.models.prototype.other", "activerecord.models.return_authorization.one", "activerecord.models.return_authorization.other", "activerecord.models.role.one", "activerecord.models.role.other", "activerecord.models.shipment.one", "activerecord.models.shipment.other", "activerecord.models.shipping_category.one", "activerecord.models.shipping_category.other", "activerecord.models.state.one", "activerecord.models.state.other", "activerecord.models.tax_category.one", "activerecord.models.tax_category.other", "activerecord.models.tax_rate.one", "activerecord.models.tax_rate.other", "activerecord.models.taxon.one", "activerecord.models.taxon.other", "activerecord.models.taxonomy.one", "activerecord.models.taxonomy.other", "activerecord.models.user.one", "activerecord.models.user.other", "activerecord.models.variant.one", "activerecord.models.variant.other", "activerecord.models.zone.one", "activerecord.models.zone.other", "errors.messages.not_found", "errors.messages.already_confirmed", "errors.messages.not_locked", "errors.messages.not_saved.one", "errors.messages.not_saved.other", "no", "yes", "5_biggest_spenders", "a_copy_of_all_mail_will_be_sent_to_the_following_addresses", "abbreviation", "access_denied", "account", "account_updated", "action", "actions.cancel", "actions.create", "actions.destroy", "actions.list", "actions.listing", "actions.new", "actions.update", "active", "add", "add_category", "add_country", "add_option_type", "add_option_types", "add_option_value", "add_product", "add_product_properties", "add_scope", "add_state", "add_to_cart", "add_zone", "additional_item", "address", "address_information", "adjustment", "adjustment_total", "adjustments", "administration", "all", "all_departments", "allow_backorders", "allow_ssl_to_be_used_when_in_developement_and_test_modes", "allow_ssl_to_be_used_when_in_production_mode", "allowed_ssl_in_production_mode", "already_registered", "alt_text", "alternative_phone", "amount", "analytics_trackers", "apply", "are_you_sure", "are_you_sure_category", "are_you_sure_delete", "are_you_sure_delete_image", "are_you_sure_option_type", "are_you_sure_you_want_to_capture", "assign_taxon", "assign_taxons", "authorization_failure", "authorized", "available_on", "available_taxons", "awaiting_return", "back", "back_end", "back_to_store", "backordered", "backordering_is_allowed", "balance_due", "best_selling_products", "best_selling_taxons", "bill_address", "billing", "billing_address", "both", "by_day", "calculator", "calculator_settings_warning", "cancel", "cancel_my_account", "cancel_my_account_description", "canceled", "cannot_create_returns", "cannot_destory_line_item_as_inventory_units_have_shipped", "cannot_perform_operation", "capture", "card_code", "card_details", "card_number", "card_type_is", "cart", "categories", "category", "change", "change_language", "change_my_password", "charge_total", "charged", "charges", "checkout", "cheque", "city", "clone", "code", "combine", "complete", "complete_list", "configuration", "configuration_options", "configurations", "configured", "confirm", "confirm_delete", "confirm_password", "continue", "continue_shopping", "copy_all_mails_to", "cost_price", "count", "count_of_reduced_by", "country", "country_based", "create", "create_a_new_account", "create_product_group_from_products", "create_user_account", "created_successfully", "credit", "credit_card", "credit_card_capture_complete", "credit_card_payment", "credit_owed", "credit_total", "creditcard", "creditcards", "credits", "current", "customer", "customer_details", "customer_search", "date_created", "date_range", "debit", "default", "delete", "depth", "description", "destroy", "didnt_receive_confirmation_instructions", "didnt_receive_unlock_instructions", "discount_amount", "display", "edit", "editing_billing_integration", "editing_category", "editing_mail_method", "editing_option_type", "editing_option_types", "editing_payment_method", "editing_product", "editing_product_group", "editing_property", "editing_prototype", "editing_shipping_category", "editing_shipping_method", "editing_state", "editing_tax_category", "editing_tax_rate", "editing_tracker", "editing_user", "editing_zone", "email", "email_address", "email_server_settings_description", "empty", "empty_cart", "enable_login_via_login_password", "enable_login_via_openid", "enable_mail_delivery", "enter_exactly_as_shown_on_card", "enter_password_to_confirm", "environment", "error", "event", "existing_customer", "expiration", "expiration_month", "expiration_year", "extension", "extensions", "filename", "final_confirmation", "finalize", "finalized_payments", "first_item", "first_name", "first_name_begins_with", "flat_percent", "flat_rate_amount", "flat_rate_per_item", "flat_rate_per_order", "flexible_rate", "forgot_password", "front_end", "full_name", "gateway", "gateway_configuration", "gateway_error", "gateway_setting_description", "gateway_settings_warning", "general", "general_settings", "general_settings_description", "google_analytics", "google_analytics_active", "google_analytics_create", "google_analytics_id", "google_analytics_new", "google_analytics_setting_description", "guest_checkout", "guest_user_account", "has_no_shipped_units", "height", "hello_user", "history", "home", "icon", "icons_by", "image", "images", "images_for", "in_progress", "include_in_shipment", "included_in_other_shipment", "included_in_this_shipment", "instructions_to_reset_password", "integration_settings_warning", "intercept_email_address", "intercept_email_instructions", "invalid_search", "inventory", "inventory_adjustment", "inventory_setting_description", "inventory_settings", "is_not_available_to_shipment_address", "issue_number", "item", "item_description", "item_total", "items", "last_14_days", "last_5_orders", "last_7_days", "last_month", "last_name", "last_name_begins_with", "last_year", "leave_blank_to_not_change", "list", "listing_categories", "listing_option_types", "listing_orders", "listing_product_groups", "listing_reports", "listing_tax_categories", "listing_users", "live", "loading", "locale_changed", "log_in", "logged_in_as", "logged_in_succesfully", "logged_out", "login", "login_as_existing", "login_failed", "login_name", "logout", "look_for_similar_items", "maestro_or_solo_cards", "mail_delivery_enabled", "mail_delivery_not_enabled", "mail_methods", "mail_server_preferences", "make_refund", "mark_shipped", "master_price", "max_items", "meta_description", "meta_keywords", "metadata", "missing_required_information", "minimal_amount", "month", "my_account", "my_orders", "name", "name_or_sku", "new", "new_adjustment", "new_billing_integration", "new_category", "new_customer", "new_image", "new_mail_method", "new_option_type", "new_option_value", "new_order", "new_order_completed", "new_payment", "new_payment_method", "new_product", "new_product_group", "new_property", "new_prototype", "new_return_authorization", "new_shipment", "new_shipping_category", "new_shipping_method", "new_state", "new_tax_category", "new_tax_rate", "new_taxon", "new_taxonomy", "new_tracker", "new_user", "new_variant", "new_zone", "next", "no_items_in_cart", "no_match_found", "no_payment_methods_available", "no_products_found", "no_results", "no_shipping_methods_available", "no_user_found", "none", "none_available", "normal_amount", "not", "not_shown", "note", "notice_messages.option_type_removed", "notice_messages.product_cloned", "notice_messages.product_deleted", "notice_messages.product_not_cloned", "notice_messages.product_not_deleted", "notice_messages.variant_deleted", "notice_messages.variant_not_deleted", "on_hand", "operation", "option_Values", "option_types", "option_values", "options", "or", "ord_qty", "ord_total", "order", "order_confirmation_note", "order_date", "order_details", "order_email_resent", "order_not_in_system", "order_number", "order_operation_authorize", "order_processed_but_following_items_are_out_of_stock", "order_processed_successfully", "order_state.address", "order_state.adjustments", "order_state.awaiting_return", "order_state.canceled", "order_state.cart", "order_state.complete", "order_state.confirm", "order_state.delivery", "order_state.payment", "order_state.resumed", "order_state.returned", "order_summary", "order_sure_want_to", "order_total", "order_total_message", "order_updated", "orders", "other_payment_options", "out_of_stock", "out_of_stock_products", "over_paid", "overview", "overview_welcome", "page_only_viewable_when_logged_in", "page_only_viewable_when_logged_out", "paid", "parent_category", "password", "password_reset_instructions", "password_reset_instructions_are_mailed", "password_reset_token_not_found", "password_updated", "path", "pay", "payment", "payment_gateway", "payment_information", "payment_method", "payment_methods", "payment_methods_setting_description", "payment_processing_failed", "payment_state", "payment_states.balance_due", "payment_states.credit_owed", "payment_states.failed", "payment_states.paid", "payment_updated", "payments", "pending_payments", "permalink", "phone", "place_order", "please_create_user", "powered_by", "presentation", "preview", "previous", "price", "price_bucket", "price_with_vat_included", "problem_authorizing_card", "problem_capturing_card", "problems_processing_order", "proceed_as_guest", "process", "product", "product_details", "product_group", "product_group_invalid", "product_groups", "product_has_no_description", "product_properties", "product_scopes.groups.price.description", "product_scopes.groups.price.name", "product_scopes.groups.search.description", "product_scopes.groups.search.name", "product_scopes.groups.taxon.description", "product_scopes.groups.taxon.name", "product_scopes.groups.values.description", "product_scopes.groups.values.name", "product_scopes.scopes.ascend_by_master_price.name", "product_scopes.scopes.ascend_by_name.name", "product_scopes.scopes.ascend_by_updated_at.name", "product_scopes.scopes.descend_by_master_price.name", "product_scopes.scopes.descend_by_name.name", "product_scopes.scopes.descend_by_popularity.name", "product_scopes.scopes.descend_by_updated_at.name", "product_scopes.scopes.in_name.args.words", "product_scopes.scopes.in_name.description", "product_scopes.scopes.in_name.name", "product_scopes.scopes.in_name.sentence", "product_scopes.scopes.in_name_or_description.args.words", "product_scopes.scopes.in_name_or_description.description", "product_scopes.scopes.in_name_or_description.name", "product_scopes.scopes.in_name_or_description.sentence", "product_scopes.scopes.in_name_or_keywords.args.words", "product_scopes.scopes.in_name_or_keywords.description", "product_scopes.scopes.in_name_or_keywords.name", "product_scopes.scopes.in_name_or_keywords.sentence", "product_scopes.scopes.in_taxons.args.taxon_names", "product_scopes.scopes.in_taxons.description", "product_scopes.scopes.in_taxons.name", "product_scopes.scopes.in_taxons.sentence", "product_scopes.scopes.master_price_gte.args.amount", "product_scopes.scopes.master_price_gte.description", "product_scopes.scopes.master_price_gte.name", "product_scopes.scopes.master_price_gte.sentence", "product_scopes.scopes.master_price_lte.args.amount", "product_scopes.scopes.master_price_lte.description", "product_scopes.scopes.master_price_lte.name", "product_scopes.scopes.master_price_lte.sentence", "product_scopes.scopes.price_between.args.high", "product_scopes.scopes.price_between.args.low", "product_scopes.scopes.price_between.description", "product_scopes.scopes.price_between.name", "product_scopes.scopes.price_between.sentence", "product_scopes.scopes.taxons_name_eq.args.taxon_name", "product_scopes.scopes.taxons_name_eq.description", "product_scopes.scopes.taxons_name_eq.name", "product_scopes.scopes.taxons_name_eq.sentence", "product_scopes.scopes.with.args.value", "product_scopes.scopes.with.description", "product_scopes.scopes.with.name", "product_scopes.scopes.with.sentence", "product_scopes.scopes.with_ids.args.ids", "product_scopes.scopes.with_ids.description", "product_scopes.scopes.with_ids.name", "product_scopes.scopes.with_ids.sentence", "product_scopes.scopes.with_option.args.option", "product_scopes.scopes.with_option.description", "product_scopes.scopes.with_option.name", "product_scopes.scopes.with_option.sentence", "product_scopes.scopes.with_option_value.args.option", "product_scopes.scopes.with_option_value.args.value", "product_scopes.scopes.with_option_value.description", "product_scopes.scopes.with_option_value.name", "product_scopes.scopes.with_option_value.sentence", "product_scopes.scopes.with_property.args.property", "product_scopes.scopes.with_property.description", "product_scopes.scopes.with_property.name", "product_scopes.scopes.with_property.sentence", "product_scopes.scopes.with_property_value.args.property", "product_scopes.scopes.with_property_value.args.value", "product_scopes.scopes.with_property_value.description", "product_scopes.scopes.with_property_value.name", "product_scopes.scopes.with_property_value.sentence", "products", "products_with_zero_inventory_display", "properties", "property", "prototype", "prototypes", "provider", "provider_settings_warning", "qty", "quantity_shipped", "quantity_returned", "range", "rate", "reason", "recalculate_order_total", "receive", "received", "refund", "register", "register_or_guest", "registration.page_title", "registration.DD", "registration.MM", "registration.YYYY", "registration.notices.registration_complete", "registration.notices.access_denied_invalid_token", "remember_me", "remove", "reports", "required_for_solo_and_maestro", "resend", "resend_confirmation_instructions", "resend_unlock_instructions", "reset_password", "resource_controller.member_object_not_found", "resource_controller.successfully_created", "resource_controller.successfully_removed", "resource_controller.successfully_updated", "response_code", "resume", "resumed", "return", "return_authorization", "return_authorization_updated", "return_authorizations", "return_quantity", "returned", "rma_credit", "rma_number", "rma_value", "roles", "sales_tax", "sales_total", "sales_total_for_all_orders", "sales_totals", "sales_totals_description", "save_and_continue", "save_preferences", "scope", "scopes", "search", "search_results", "searching", "secure_connection_type", "secure_creditcard", "select", "select_from_prototype", "select_preferred_shipping_option", "send_copy_of_all_mails_to", "send_copy_of_orders_mails_to", "send_mails_as", "send_me_reset_password_instructions", "send_order_mails_as", "server", "server_error", "settings", "ship", "ship_address", "shipment", "shipment_details", "shipment_number", "shipment_state", "shipment_states.backorder", "shipment_states.partial", "shipment_states.pending", "shipment_states.ready", "shipment_states.shipped", "shipment_updated", "shipments", "shipped", "shipping", "shipping_address", "shipping_categories", "shipping_categories_description", "shipping_category", "shipping_cost", "shipping_error", "shipping_instructions", "shipping_method", "shipping_methods", "shipping_methods_description", "shipping_total", "shop_by_taxonomy", "shopping_cart", "show", "show_active", "show_deleted", "show_incomplete_orders", "show_only_complete_orders", "show_out_of_stock_products", "show_price_inc_vat", "showing_first_n", "sign_up", "site_name", "site_url", "sku", "smtp", "smtp_authentication_type", "smtp_domain", "smtp_mail_host", "smtp_password", "smtp_port", "smtp_send_all_emails_as_from_following_address", "smtp_send_copy_to_this_addresses", "smtp_username", "sold", "sort_ordering", "special_instructions", "spree.date", "spree.time", "spree_gateway_error_flash_for_checkout", "ssl_will_be_used_in_development_and_test_modes", "ssl_will_be_used_in_production_mode", "ssl_will_not_be_used_in_development_and_test_modes", "ssl_will_not_be_used_in_production_mode", "start", "start_date", "state", "state_based", "state_setting_description", "states", "status", "stop", "store", "street_address", "street_address_2", "subtotal", "subtract", "system", "tax", "tax_categories", "tax_categories_setting_description", "tax_category", "tax_rates", "tax_rates_description", "tax_settings", "tax_settings_description", "tax_total", "tax_type", "taxon", "taxon_edit", "taxonomies", "taxonomies_setting_description", "taxonomy_edit", "taxonomy_tree_error", "taxonomy_tree_instruction", "taxons", "test", "test_mode", "thank_you_for_your_order", "this_file_language", "this_month", "this_year", "thumbnail", "to_add_variants_you_must_first_define", "top_grossing_products", "total", "tracking", "transaction", "transactions", "tree", "try_again", "type", "type_to_search", "unable_ship_method", "unable_to_authorize_credit_card", "unable_to_capture_credit_card", "unable_to_connect_to_gateway", "unable_to_save_order", "under_paid", "units", "unrecognized_card_type", "update", "update_password", "updated_successfully", "updating", "usage_limit", "use_as_shipping_address", "use_billing_address", "use_different_shipping_address", "use_new_cc", "user", "user_account", "user_created_successfully", "user_details", "users", "validate_on_profile_create", "validation.cannot_be_less_than_shipped_units", "validation.is_too_large", "validation.must_be_int", "validation.must_be_non_negative", "value", "variants", "vat", "version", "view_shipping_options", "void", "website", "weight", "welcome_to_sample_store", "what_is_a_cvv", "what_is_this", "whats_this", "width", "year", "you_have_been_logged_out", "your_cart_is_empty", "zip", "zone", "zone_based", "zone_setting_description", "zones", "devise.failure.unauthenticated", "devise.failure.unconfirmed", "devise.failure.locked", "devise.failure.invalid", "devise.failure.invalid_token", "devise.failure.timeout", "devise.failure.inactive", "devise.sessions.signed_in", "devise.sessions.signed_out", "devise.passwords.send_instructions", "devise.passwords.updated", "devise.confirmations.send_instructions", "devise.confirmations.confirmed", "devise.registrations.signed_up", "devise.registrations.inactive_signed_up", "devise.registrations.updated", "devise.registrations.destroyed", "devise.unlocks.send_instructions", "devise.unlocks.unlocked", "devise.omniauth_callbacks.success", "devise.omniauth_callbacks.failure", "devise.mailer.confirmation_instructions.subject", "devise.mailer.reset_password_instructions.subject", "devise.mailer.unlock_instructions.subject", "devise.user_password_resets.send_instructions", "devise.user_password_resets.updated", "devise.user_registrations.signed_up", "devise.user_registrations.inactive_signed_up", "devise.user_registrations.updated", "devise.user_registrations.destroyed", "devise.user_registrations.user.sent_confirmation_email_message", "devise.user_sessions.signed_in", "devise.user_sessions.signed_out", "devise.oauth_callbacks.success", "devise.oauth_callbacks.failure", "api.access", "api.clear_key", "api.errors.invalid_event", "api.errors.invalid_event_for_object", "api.errors.missing_event", "api.generate_key", "api.key", "api.regenerate_key", "api.no_key", "api.key_generated", "api.key_cleared", "add_rule_of_type", "coupon", "coupon_code", "editing_promotion", "free_shipping", "new_promotion", "no_rules_added", "promotions", "promotion_form.match_policies.all", "promotion_form.match_policies.any", "promotions_description", "promotion_rule_types.user.name", "promotion_rule_types.user.description", "promotion_rule_types.product.name", "promotion_rule_types.product.description", "promotion_rule_types.item_total.name", "promotion_rule_types.item_total.description", "promotion_rule_types.first_order.name", "promotion_rule_types.first_order.description", "product_rule.choose_products", "product_rule.label", "product_rule.match_any", "product_rule.match_all", "product_rule.product_source.group", "product_rule.product_source.manual", "user_rule.choose_users", "item_total_rule.operators.gt", "item_total_rule.operators.gte", "mailer.confirmation.greeting", "mailer.confirmation.subject", "mailer.confirmation.message", "mailer.confirmation.thanking", "mailer.footer.message", "mailer.footer.unsubscribe"]
Translator.framework_keys = (Translator.framework_keys + spree_keys).uniq

User stories

Current features:

As a user, I want to translate my Rails 3 application to different languages, so that more visitors can use it in their native languages.

As a developer, I want to specify custom authorization proc, so that I can integrate with my application nicely.

As a developer, I want to have nice layout for translations module, so I don’t have to bother with integrating with my admin panel, and have some JavaScript.

As a user, I want to have default translations for languages loaded from config/*.yml files, so that I can use translation module with existing applications.

As a user, I want to have default translations loaded from Rails’ built in translation files, so that things like validation errors are present for English language.

As a user, I want to have all Rails translations hidden in ‘Framework Translations’, so that user can focus primarily on application-specific strings.

As a developer, I want to override list of ‘Framework Translations’ with a custom specified in initializer.

As a user, I want to revert to default translation, loaded from YAML file, by clicking on ‘Default’ link.

Ad a user, I want to choose between Redis and MongoDB for translations storage.

Future features:

As a user, I want to have all strings I enter validated, based on values from *.yml files, so I cannot break the app with malformed translations (ie. with wrong number of parameters).

As a user, I want to export full translations for given language to *yml file, which is syntax-compatible with Rails’ default backend, so that I can move it to the other application or disable translate_yourself completely.

As a user, I want to import full or partial translations for given language from *yml file, skipping keys that are not present in default language.

Thanks

David Heinemeier Hansson for github.com/dhh/tolk, Ryan Bates for I18n::Backend screencast railscasts.com/episodes/256-i18n-backends.

Copyright and License

Copyright by Hubert Łępicki, 2010-2011. Find me at [email protected].

This software is licensed under the terms of MIT-LICENSE.

translator's People

Contributors

dmips avatar hubertlepicki avatar romanbsd avatar wpiekutowski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

translator's Issues

undefined method `keys' for #<Array:0x1057e9720>

I installed the gem. Configured for mongo. Open browser to /translations and get the following error

NoMethodError in Translator::translationsController#index

undefined method `keys' for #Array:0x1057e9720

Rails.root: /Users/jroodnat/Appdev/Rails/workplace
Application Trace | Framework Trace | Full Trace

/lib/serve_gridfs_image.rb:19:in `call'

/Library/Ruby/Gems/1.8/bundler/gems/translator-290229451e89/lib/translator.rb:59:in keys_for_strings' /Library/Ruby/Gems/1.8/bundler/gems/translator-290229451e89/app/controllers/translator/translations_controller.rb:6:inindex'
actionpack (3.0.4) lib/action_controller/metal/implicit_render.rb:4:in send_action' actionpack (3.0.4) lib/action_controller/metal/implicit_render.rb:4:insend_action'
actionpack (3.0.4) lib/abstract_controller/base.rb:150:in process_action' actionpack (3.0.4) lib/action_controller/metal/rendering.rb:11:inprocess_action'
actionpack (3.0.4) lib/abstract_controller/callbacks.rb:18:in process_action' activesupport (3.0.4) lib/active_support/callbacks.rb:440:in_run__459127869__process_action__199225275__callbacks'
activesupport (3.0.4) lib/active_support/callbacks.rb:409:in send' activesupport (3.0.4) lib/active_support/callbacks.rb:409:in_run_process_action_callbacks'
activesupport (3.0.4) lib/active_support/callbacks.rb:93:in send' activesupport (3.0.4) lib/active_support/callbacks.rb:93:inrun_callbacks'
actionpack (3.0.4) lib/abstract_controller/callbacks.rb:17:in process_action' actionpack (3.0.4) lib/action_controller/metal/instrumentation.rb:30:inprocess_action'
activesupport (3.0.4) lib/active_support/notifications.rb:52:in instrument' activesupport (3.0.4) lib/active_support/notifications/instrumenter.rb:21:ininstrument'
activesupport (3.0.4) lib/active_support/notifications.rb:52:in instrument' actionpack (3.0.4) lib/action_controller/metal/instrumentation.rb:29:inprocess_action'
actionpack (3.0.4) lib/action_controller/metal/rescue.rb:17:in process_action' actionpack (3.0.4) lib/abstract_controller/base.rb:119:inprocess'
actionpack (3.0.4) lib/abstract_controller/rendering.rb:41:in process' actionpack (3.0.4) lib/action_controller/metal.rb:138:indispatch'
actionpack (3.0.4) lib/action_controller/metal/rack_delegation.rb:14:in dispatch' actionpack (3.0.4) lib/action_controller/metal.rb:178:inaction'
actionpack (3.0.4) lib/action_dispatch/routing/route_set.rb:62:in call' actionpack (3.0.4) lib/action_dispatch/routing/route_set.rb:62:indispatch'
actionpack (3.0.4) lib/action_dispatch/routing/route_set.rb:27:in call' rack-mount (0.6.13) lib/rack/mount/route_set.rb:148:incall'
rack-mount (0.6.13) lib/rack/mount/code_generation.rb:93:in recognize' rack-mount (0.6.13) lib/rack/mount/code_generation.rb:75:inoptimized_each'
rack-mount (0.6.13) lib/rack/mount/code_generation.rb:92:in recognize' rack-mount (0.6.13) lib/rack/mount/route_set.rb:139:incall'
actionpack (3.0.4) lib/action_dispatch/routing/route_set.rb:492:in call' warden (1.0.3) lib/warden/manager.rb:35:incall'
warden (1.0.3) lib/warden/manager.rb:34:in catch' warden (1.0.3) lib/warden/manager.rb:34:incall'
actionpack (3.0.4) lib/action_dispatch/middleware/best_standards_support.rb:17:in call' actionpack (3.0.4) lib/action_dispatch/middleware/head.rb:14:incall'
rack (1.2.1) lib/rack/methodoverride.rb:24:in call' actionpack (3.0.4) lib/action_dispatch/middleware/params_parser.rb:21:incall'
actionpack (3.0.4) lib/action_dispatch/middleware/flash.rb:182:in call' actionpack (3.0.4) lib/action_dispatch/middleware/session/abstract_store.rb:149:incall'
flash_cookie_session (1.1.0) lib/flash_cookie_session/middleware.rb:15:in call' actionpack (3.0.4) lib/action_dispatch/middleware/cookies.rb:302:incall'
actionpack (3.0.4) lib/action_dispatch/middleware/callbacks.rb:46:in call' activesupport (3.0.4) lib/active_support/callbacks.rb:415:in_run_call_callbacks'
actionpack (3.0.4) lib/action_dispatch/middleware/callbacks.rb:44:in call' rack (1.2.1) lib/rack/sendfile.rb:107:incall'
actionpack (3.0.4) lib/action_dispatch/middleware/remote_ip.rb:48:in call' actionpack (3.0.4) lib/action_dispatch/middleware/show_exceptions.rb:47:incall'
railties (3.0.4) lib/rails/rack/logger.rb:13:in call' rack (1.2.1) lib/rack/runtime.rb:17:incall'
activesupport (3.0.4) lib/active_support/cache/strategy/local_cache.rb:72:in call' rack (1.2.1) lib/rack/lock.rb:11:incall'
rack (1.2.1) lib/rack/lock.rb:11:in synchronize' rack (1.2.1) lib/rack/lock.rb:11:incall'
actionpack (3.0.4) lib/action_dispatch/middleware/static.rb:30:in call' railties (3.0.4) lib/rails/application.rb:168:incall'
railties (3.0.4) lib/rails/application.rb:77:in send' railties (3.0.4) lib/rails/application.rb:77:inmethod_missing'
railties (3.0.4) lib/rails/rack/debugger.rb:21:in call' railties (3.0.4) lib/rails/rack/log_tailer.rb:14:incall'
rack (1.2.1) lib/rack/content_length.rb:13:in call' rack (1.2.1) lib/rack/handler/webrick.rb:52:inservice'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in service' /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/httpserver.rb:65:inrun'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:173:in start_thread' /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:162:instart'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:162:in start_thread' /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:95:instart'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:92:in each' /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:92:instart'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:23:in start' /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:82:instart'
rack (1.2.1) lib/rack/handler/webrick.rb:13:in run' rack (1.2.1) lib/rack/server.rb:213:instart'
railties (3.0.4) lib/rails/commands/server.rb:65:in start' railties (3.0.4) lib/rails/commands.rb:30 railties (3.0.4) lib/rails/commands.rb:27:intap'
railties (3.0.4) lib/rails/commands.rb:27
script/rails:6:in `require'
script/rails:6

/Library/Ruby/Gems/1.8/bundler/gems/translator-290229451e89/lib/translator.rb:59:in keys_for_strings' /Library/Ruby/Gems/1.8/bundler/gems/translator-290229451e89/app/controllers/translator/translations_controller.rb:6:inindex'

Make it easy to use translation strings from JavaScript

I think the Translator should provide and API, that would allow fetching the translations to JavaScript and mobile clients.

We have a valid use case in project me, Iryna and Marcin work on at the moment, where we have custom API endpoint that outputs all the translations to JSON, to format easily usable with angular-translate library (https://github.com/angular-translate/angular-translate).

The implementation in the translator could be very similar. But I think the request should specify what locales we want to fetch, i.e. do not output all available locales at once (too many), and have endpoint like /translations/en.json or something that would fetch only those locale that are needed.

Get rid of MongoDB

It is too slow. Only key-value stores can be used, I think we're good with Redis, we can consider adding others in future. But MongoDB is not so great and I do not see valid use case to keep it.

Develop mechanism for easy synchronisation from staging to prod

The usual case that we use translator is that client translates the web site on staging, and the translations are being pulled into production. I think there is a rake task and api that @dziemian007 developed somewhere, maybe on branch "rb". But I am unsure if this is correct solution.

We need something that would work with both capistrano and heroku.

The feature needs pondering about, proper design of the process and implementation and documenting of the process so other developers can use it.

Page not found

Doesn't seem to work with Rails 3.2.x. Getting a Page not found.

Re-write user interface

Curren user interface... kind of works. It's slow and ugly. I think it needs a rewrite.

What I was thinking about was a nice Angular.js and bootstrap based solution. I do not think we need a huge form with 2-way bindings, maybe we can live with a list of translations, and it only changes into editable form once you click on it.

There should be search and finding out relevant translations via filters as it is now.

The back-end can be extracted to form an API that can be used for in-line editing (see: #11)

In-line editing

This one is quite far-fetched, but something a client suggested. It would be great to allow in-line editing of some sort. What I mean is that you just go to some page of your app, and you see what are the transltions and you can updte/save them from that given page. Much like mercury editor does, but it can be also a link somewhere 'translate this page' that opens a form with all the translations used on this page.

Not sure how this would work with parts of page loaded via ajax, iframes etc, and also translations used in JavaScript (see #12)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.