├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── activeadmin-translate.gemspec ├── app └── assets │ └── stylesheets │ └── active_admin │ └── translate.css.scss ├── config └── locales │ ├── de.yml │ ├── en.yml │ ├── fr.yml │ └── it.yml └── lib ├── active_admin ├── translate │ ├── engine.rb │ ├── form_builder.rb │ └── version.rb └── views │ └── translate_attributes_table.rb └── activeadmin-translate.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | Gemfile.lock 7 | InstalledFiles 8 | _yardoc 9 | coverage 10 | doc/ 11 | lib/bundler/man 12 | pkg 13 | rdoc 14 | spec/reports 15 | test/tmp 16 | test/version_tmp 17 | tmp 18 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # ActiveAdmin Translate Changelog 2 | 3 | ## 0.2.2 - November 16, 2012 4 | 5 | - Include SCSS mixins. 6 | 7 | ## 0.2.1 - November 16, 2012 8 | 9 | - Do not loose nested translations on error. 10 | 11 | ## 0.2.0 - November 15, 2012 12 | 13 | - Add `de`, `fr` and `it` to translations. 14 | - Fix tab rendering when editing `has_many` relations. 15 | 16 | ## 0.1.0 - November 15, 2012 17 | 18 | - Initial version 19 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contribute to ActiveAdmin Translate 2 | =================================== 3 | 4 | File an issue 5 | ------------- 6 | 7 | You can report bugs and feature requests to [GitHub Issues](https://github.com/netzpirat/activeadmin-globalize/issues). 8 | 9 | **Please don't ask question in the issue tracker**, instead ask them at Stackoverflow and use the 10 | [activeadmin](http://stackoverflow.com/questions/tagged/activeadmin) tag. 11 | 12 | When you file a bug, please try to follow these simple rules if applicable: 13 | 14 | * Make sure you've read the README carefully. 15 | * Give as much information about your environment, like Ruby and ActiveAdmin version. 16 | * Make sure that the issue is reproducible with your description. 17 | 18 | **It's most likely that your bug gets resolved faster if you provide as much information as possible!** 19 | 20 | Development 21 | ----------- 22 | 23 | * Documentation hosted at [RubyDoc](http://rubydoc.info/github/netzpirat/activeadmin-globalize/master/frames). 24 | * Source hosted at [GitHub](https://github.com/netzpirat/activeadmin-globalize). 25 | 26 | Pull requests are very welcome! Please try to follow these simple rules if applicable: 27 | 28 | * Please create a topic branch for every separate change you make. 29 | * Update the [Yard](http://yardoc.org/) documentation. 30 | * Update the [README](https://github.com/netzpirat/haml_coffee_assets/blob/master/README.md). 31 | * Update the [CHANGELOG](https://github.com/netzpirat/haml_coffee_assets/blob/master/CHANGELOG.md) for noteworthy changes. 32 | * Please **do not change** the version number. 33 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Michael Kessler 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ActiveAdmin Translate 2 | 3 | Translate your [Globalize3](https://github.com/svenfuchs/globalize3) ActiveModel translations in 4 | [ActiveAdmin](https://github.com/gregbell/active_admin), using [jQueryUI tabs](http://jqueryui.com/tabs/) to switch 5 | between the locales. 6 | 7 | ## Installation 8 | 9 | Add the gem to your `Gemfile` 10 | 11 | ```ruby 12 | gem 'activeadmin-translate' 13 | ``` 14 | 15 | and install it with Bundler: 16 | 17 | ```Bash 18 | $ bundle 19 | ``` 20 | 21 | ## Configuration 22 | 23 | ### Set available languages 24 | 25 | ActiveAdmin Translate takes the available languages from `I18n.available_locales`, so you want to configure them in 26 | your `application.rb` like 27 | 28 | ```ruby 29 | config.i18n.available_locales = [:en, :de, :fr, :it] 30 | ``` 31 | 32 | ### Include ActiveAdmin Translate 33 | 34 | You need to import the SASS for styling the tabs to `app/assets/stylesheets/active_admin.css.scss`: 35 | 36 | ```css 37 | @import "active_admin/translate"; 38 | ``` 39 | 40 | ## Usage 41 | 42 | ### Make your translations accessible 43 | 44 | In order to access the translations of your model and be able to write them on save, you need to make attributes 45 | accessible in your model. Globalize3 stores the model translations in a separate table that is accessible as 46 | `translations` in your model: 47 | 48 | ```ruby 49 | class GlobalizedModel < ActiveRecord::Base 50 | attr_accessible :translations, :translations_attributes 51 | accepts_nested_attributes_for :translations 52 | end 53 | ``` 54 | 55 | ### Translate your ActiveAdmin forms 56 | 57 | To translate your form you need to use the `translate_inputs` form helper: 58 | 59 | ```ruby 60 | form do |f| 61 | f.translate_inputs do |t| 62 | t.input :title 63 | t.input :description 64 | end 65 | end 66 | ``` 67 | 68 | ### Translate your ActiveAdmin attributes table 69 | 70 | To show the attributes for all locales, you use the `translate_attributes_table_for` view helper: 71 | 72 | ```ruby 73 | show do |model| 74 | panel 'Globalized Model' do 75 | translate_attributes_table_for model do 76 | row :title 77 | row :description do |p| 78 | BlueCloth.new(p.teaser).to_html.html_safe 79 | end 80 | end 81 | end 82 | end 83 | ``` 84 | 85 | ### Localize the languages 86 | 87 | To localize your locale names, use the following I18n key structure per locale: 88 | 89 | ```yml 90 | en: 91 | active_admin: 92 | translate: 93 | en: "English" 94 | ``` 95 | 96 | and add more translations with the registered locale symbol. 97 | 98 | ## Author 99 | 100 | Developed by Michael Kessler, [FlinkFinger GmbH](http://www.flinkfinger.com). 101 | 102 | If you like ActiveAdmin Translate, you can watch the repository at 103 | [GitHub](https://github.com/netzpirat/activeadmin-globalize) and follow [@netzpirat](https://twitter.com/#!/netzpirat) 104 | on Twitter for project updates. 105 | 106 | ## Contribute to ActiveAdmin Translate 107 | 108 | ### File an issue 109 | 110 | You can report bugs and feature requests to [GitHub Issues](https://github.com/netzpirat/activeadmin-globalize/issues). 111 | 112 | **Please don't ask question in the issue tracker**, instead ask them at Stackoverflow and use the 113 | [activeadmin](http://stackoverflow.com/questions/tagged/activeadmin) tag. 114 | 115 | When you file a bug, please try to follow these simple rules if applicable: 116 | 117 | * Make sure you've read the README carefully. 118 | * Give as much information about your environment, like Ruby and ActiveAdmin version. 119 | * Make sure that the issue is reproducible with your description. 120 | 121 | **It's most likely that your bug gets resolved faster if you provide as much information as possible!** 122 | 123 | ### Development 124 | 125 | * Documentation hosted at [RubyDoc](http://rubydoc.info/github/netzpirat/activeadmin-globalize/master/frames). 126 | * Source hosted at [GitHub](https://github.com/netzpirat/activeadmin-globalize). 127 | 128 | Pull requests are very welcome! Please try to follow these simple rules if applicable: 129 | 130 | * Please create a topic branch for every separate change you make. 131 | * Update the [Yard](http://yardoc.org/) documentation. 132 | * Update the [README](https://github.com/netzpirat/activeadmin-globalize/blob/master/README.md). 133 | * Update the [CHANGELOG](https://github.com/netzpirat/activeadmin-globalize/blob/master/CHANGELOG.md) for noteworthy changes. 134 | * Please **do not change** the version number. 135 | 136 | ## Contributors 137 | 138 | See the [CHANGELOG](https://github.com/netzpirat/activeadmin-globalize/blob/master/CHANGELOG.md) and the GitHub list of 139 | [contributors](https://github.com/netzpirat/activeadmin-globalize/contributors). 140 | 141 | ## Acknowledgment 142 | 143 | This project has taken some ideas and code from the following projects: 144 | 145 | - [activeadmin-globalize3](https://github.com/stefanoverna/activeadmin-globalize3) from [Stefano Verna](https://github.com/stefanoverna) 146 | - [ActiveAdmin-Globalize3-inputs](https://github.com/mimimi/ActiveAdmin-Globalize3-inputs) from [Dmitrii Soltis](https://github.com/mimimi) 147 | 148 | ## License 149 | 150 | Copyright (c) 2012 Michael Kessler 151 | 152 | MIT License 153 | 154 | Permission is hereby granted, free of charge, to any person obtaining 155 | a copy of this software and associated documentation files (the 156 | "Software"), to deal in the Software without restriction, including 157 | without limitation the rights to use, copy, modify, merge, publish, 158 | distribute, sublicense, and/or sell copies of the Software, and to 159 | permit persons to whom the Software is furnished to do so, subject to 160 | the following conditions: 161 | 162 | The above copyright notice and this permission notice shall be 163 | included in all copies or substantial portions of the Software. 164 | 165 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 166 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 167 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 168 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 169 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 170 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 171 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 172 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | require 'bundler/gem_tasks' 3 | -------------------------------------------------------------------------------- /activeadmin-translate.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | require File.expand_path('../lib/active_admin/translate/version', __FILE__) 3 | 4 | Gem::Specification.new do |gem| 5 | gem.authors = ['Michael Kessler'] 6 | gem.email = %w(michi@flinkfinger.com) 7 | gem.summary = %q{Translate models with ActiveAdmin.} 8 | gem.description = %q{Translate your models in ActiveAdmin with Globalize3.} 9 | gem.homepage = 'https://github.com/netzpirat/activeadmin-translate' 10 | 11 | gem.files = Dir['{app,lib,config}/**/*'] + %w(LICENSE README.md CHANGELOG.md CONTRIBUTING.md) 12 | gem.name = 'activeadmin-translate' 13 | gem.require_paths = %w(lib) 14 | gem.version = ActiveAdmin::Translate::VERSION 15 | 16 | gem.add_dependency 'activeadmin' 17 | gem.add_dependency 'globalize3' 18 | gem.add_dependency 'railties' 19 | end 20 | -------------------------------------------------------------------------------- /app/assets/stylesheets/active_admin/translate.css.scss: -------------------------------------------------------------------------------- 1 | @import "active_admin/mixins"; 2 | 3 | .active_admin { 4 | 5 | .activeadmin-translate .locales { 6 | overflow: auto; 7 | margin-right: 10px; 8 | 9 | li { 10 | @include section-header; 11 | 12 | border-top-left-radius: 10px; 13 | border-top-right-radius: 10px; 14 | 15 | float: right !important; 16 | 17 | &.ui-state-active { 18 | background: white; 19 | } 20 | } 21 | } 22 | 23 | .has_many_fields .activeadmin-translate .locales { 24 | padding-top: 10px !important; 25 | } 26 | 27 | .activeadmin-translate .locale { 28 | clear: left; 29 | } 30 | 31 | .activeadmin-translate .ui-tabs-hide { 32 | display: none !important; 33 | } 34 | 35 | .ui-tabs { 36 | position: relative; 37 | padding: .2em; 38 | zoom: 1; 39 | } 40 | 41 | .ui-tabs .ui-tabs-nav { 42 | margin: 0; 43 | padding: .2em .2em 0; 44 | } 45 | 46 | .ui-tabs .ui-tabs-nav li { 47 | list-style: none; 48 | float: left; 49 | position: relative; 50 | top: 0; 51 | margin: 1px .2em 0 0; 52 | border-bottom: 0; 53 | padding: 0; 54 | white-space: nowrap; 55 | } 56 | 57 | .ui-tabs .ui-tabs-nav li a { 58 | float: left; 59 | padding: .5em 1em; 60 | text-decoration: none; 61 | } 62 | 63 | .ui-tabs .ui-tabs-nav li.ui-tabs-active { 64 | margin-bottom: -1px; 65 | padding-bottom: 1px; 66 | } 67 | 68 | .ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-tabs-loading a { 69 | cursor: text; 70 | } 71 | 72 | .ui-tabs .ui-tabs-nav li a, .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { 73 | cursor: pointer; 74 | } 75 | 76 | .ui-tabs .ui-tabs-panel { 77 | display: block; 78 | border-width: 0; 79 | padding: 1em 1.4em; 80 | background: none; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /config/locales/de.yml: -------------------------------------------------------------------------------- 1 | de: 2 | active_admin: 3 | translate: 4 | en: 'Englisch' 5 | de: 'Deutsch' 6 | fr: 'Französich' 7 | it: 'Italienisch' 8 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | active_admin: 3 | translate: 4 | en: 'English' 5 | de: 'German' 6 | fr: 'French' 7 | it: 'Italian' 8 | -------------------------------------------------------------------------------- /config/locales/fr.yml: -------------------------------------------------------------------------------- 1 | fr: 2 | active_admin: 3 | translate: 4 | en: 'Anglais' 5 | de: 'Allemand' 6 | fr: 'Français' 7 | it: 'Italien' 8 | -------------------------------------------------------------------------------- /config/locales/it.yml: -------------------------------------------------------------------------------- 1 | it: 2 | active_admin: 3 | translate: 4 | en: 'Inglese ' 5 | de: 'Alemanno' 6 | fr: 'Francese ' 7 | it: 'Italiano' 8 | -------------------------------------------------------------------------------- /lib/active_admin/translate/engine.rb: -------------------------------------------------------------------------------- 1 | module ActiveAdmin 2 | module Translate 3 | 4 | # ActiveAdmin Translate engine to provide the needed assets. 5 | # 6 | class Engine < ::Rails::Engine 7 | 8 | initializer 'ActiveAdmin Translate precompile' do |app| 9 | app.config.assets.precompile += %w(active_admin/translate.css) 10 | end 11 | 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/active_admin/translate/form_builder.rb: -------------------------------------------------------------------------------- 1 | module ActiveAdmin 2 | module Translate 3 | 4 | # Form builder to build input fields that are arranged by locale in tabs. 5 | # 6 | module FormBuilder 7 | 8 | # Create the local field sets to enter the inputs per locale 9 | # 10 | # @param [Symbol] name the name of the translation association 11 | # @param [Proc] block the block for the additional inputs 12 | # 13 | def translate_inputs(name = :translations, &block) 14 | form_buffers.last << template.content_tag(:div, :class => "activeadmin-translate #{ translate_id }") do 15 | locale_tabs << locale_fields(name, block) << tab_script 16 | end 17 | end 18 | 19 | protected 20 | 21 | # Create the script to activate the tabs on insertion. 22 | # 23 | # @return [String] the script tag 24 | # 25 | def tab_script 26 | template.content_tag(:script, "$('.activeadmin-translate').tabs();".html_safe) 27 | end 28 | 29 | # Create the local field sets to enter the inputs per locale. 30 | # 31 | # @param [Symbol] name the name of the translation association 32 | # @param [Proc] block the block for the additional inputs 33 | # 34 | def locale_fields(name, block) 35 | ::I18n.available_locales.map do |locale| 36 | translation = object.translation_for(locale) 37 | translation.instance_variable_set(:@errors, object.errors) if locale == I18n.default_locale 38 | 39 | fields = proc do |form| 40 | form.input(:locale, :as => :hidden) 41 | block.call(form) 42 | end 43 | 44 | inputs_for_nested_attributes(:for => [name, translation], :id => field_id(locale), :class => "inputs locale locale-#{ locale }", &fields) 45 | end.join.html_safe 46 | end 47 | 48 | 49 | # Create the locale tab to switch the translations. 50 | # 51 | # @return [String] the HTML for the locale tabs 52 | # 53 | def locale_tabs 54 | template.content_tag(:ul, :class => 'locales') do 55 | ::I18n.available_locales.map do |locale| 56 | template.content_tag(:li) do 57 | template.content_tag(:a, ::I18n.t("active_admin.translate.#{ locale }"), :href => "##{ field_id(locale) }") 58 | end 59 | end.join.html_safe 60 | end 61 | end 62 | 63 | # Get the unique id for the translation field 64 | # 65 | def field_id(locale) 66 | "locale-#{ locale }-#{ translate_id }" 67 | end 68 | 69 | # Get the unique id for the translation 70 | # 71 | # @return [String] the id 72 | # 73 | def translate_id 74 | "#{ self.object.class.to_s.underscore.dasherize }-#{ self.object.object_id }" 75 | end 76 | 77 | end 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /lib/active_admin/translate/version.rb: -------------------------------------------------------------------------------- 1 | module ActiveAdmin 2 | module Translate 3 | # The current released version 4 | VERSION = '0.2.2' 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /lib/active_admin/views/translate_attributes_table.rb: -------------------------------------------------------------------------------- 1 | module ActiveAdmin 2 | module Translate 3 | 4 | # Adds a builder method `translate_attributes_table_for` to build a 5 | # table with translations for a model that has been localized with 6 | # Globalize3. 7 | # 8 | class TranslateAttributesTable < ::ActiveAdmin::Views::AttributesTable 9 | 10 | builder_method :translate_attributes_table_for 11 | 12 | def row(attr, &block) 13 | ::I18n.available_locales.each_with_index do |locale, index| 14 | @table << tr do 15 | if index == 0 16 | th :rowspan => ::I18n.available_locales.length do 17 | header_content_for(attr) 18 | end 19 | end 20 | td do 21 | ::I18n.with_locale locale do 22 | content_for(block || attr) 23 | end 24 | end 25 | end 26 | end 27 | end 28 | 29 | protected 30 | 31 | def default_id_for_prefix 32 | 'attributes_table' 33 | end 34 | 35 | def default_class_name 36 | 'attributes_table' 37 | end 38 | 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/activeadmin-translate.rb: -------------------------------------------------------------------------------- 1 | require 'active_admin' 2 | require 'globalize3' 3 | 4 | require 'active_admin/version' 5 | require 'active_admin/translate/engine' 6 | require 'active_admin/translate/form_builder' 7 | require 'active_admin/views/translate_attributes_table' 8 | 9 | ActiveAdmin::FormBuilder.send(:include, ::ActiveAdmin::Translate::FormBuilder) 10 | --------------------------------------------------------------------------------