form_translation 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +7 -0
  4. data/Gemfile +22 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +71 -0
  7. data/Rakefile +34 -0
  8. data/app/assets/images/form_translation/.keep +0 -0
  9. data/app/assets/javascripts/form_translation/.keep +0 -0
  10. data/app/assets/stylesheets/form_translation/.keep +0 -0
  11. data/app/controllers/.keep +0 -0
  12. data/app/helpers/.keep +0 -0
  13. data/app/mailers/.keep +0 -0
  14. data/app/models/.keep +0 -0
  15. data/app/views/.keep +0 -0
  16. data/bin/rails +8 -0
  17. data/config/routes.rb +2 -0
  18. data/form_translation.gemspec +26 -0
  19. data/lib/form_translation.rb +26 -0
  20. data/lib/form_translation/active_record.rb +27 -0
  21. data/lib/form_translation/custom_form_builder.rb +22 -0
  22. data/lib/form_translation/engine.rb +10 -0
  23. data/lib/form_translation/errors.rb +5 -0
  24. data/lib/form_translation/for_model.rb +76 -0
  25. data/lib/form_translation/languages_form_builder.rb +73 -0
  26. data/lib/form_translation/version.rb +3 -0
  27. data/lib/form_translation/view_helper.rb +26 -0
  28. data/lib/tasks/form_translation_tasks.rake +4 -0
  29. data/test/dummy/README.rdoc +28 -0
  30. data/test/dummy/Rakefile +6 -0
  31. data/test/dummy/app/assets/images/.keep +0 -0
  32. data/test/dummy/app/assets/javascripts/application.js +16 -0
  33. data/test/dummy/app/assets/javascripts/articles.js +2 -0
  34. data/test/dummy/app/assets/stylesheets/application.css.scss +15 -0
  35. data/test/dummy/app/assets/stylesheets/articles.css +4 -0
  36. data/test/dummy/app/assets/stylesheets/scaffold.css +56 -0
  37. data/test/dummy/app/controllers/application_controller.rb +5 -0
  38. data/test/dummy/app/controllers/articles_controller.rb +59 -0
  39. data/test/dummy/app/controllers/concerns/.keep +0 -0
  40. data/test/dummy/app/helpers/application_helper.rb +2 -0
  41. data/test/dummy/app/helpers/articles_helper.rb +2 -0
  42. data/test/dummy/app/mailers/.keep +0 -0
  43. data/test/dummy/app/models/.keep +0 -0
  44. data/test/dummy/app/models/article.rb +5 -0
  45. data/test/dummy/app/models/concerns/.keep +0 -0
  46. data/test/dummy/app/views/articles/_form.html.erb +14 -0
  47. data/test/dummy/app/views/articles/edit.html.erb +6 -0
  48. data/test/dummy/app/views/articles/index.html.erb +31 -0
  49. data/test/dummy/app/views/articles/new.html.erb +5 -0
  50. data/test/dummy/app/views/articles/show.html.erb +19 -0
  51. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  52. data/test/dummy/bin/bundle +3 -0
  53. data/test/dummy/bin/rails +4 -0
  54. data/test/dummy/bin/rake +4 -0
  55. data/test/dummy/config.ru +4 -0
  56. data/test/dummy/config/application.rb +23 -0
  57. data/test/dummy/config/boot.rb +5 -0
  58. data/test/dummy/config/database.yml +25 -0
  59. data/test/dummy/config/environment.rb +5 -0
  60. data/test/dummy/config/environments/development.rb +31 -0
  61. data/test/dummy/config/environments/production.rb +80 -0
  62. data/test/dummy/config/environments/test.rb +36 -0
  63. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  64. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  65. data/test/dummy/config/initializers/form_translation.rb +5 -0
  66. data/test/dummy/config/initializers/inflections.rb +16 -0
  67. data/test/dummy/config/initializers/mime_types.rb +5 -0
  68. data/test/dummy/config/initializers/secret_token.rb +12 -0
  69. data/test/dummy/config/initializers/session_store.rb +3 -0
  70. data/test/dummy/config/initializers/simple_form.rb +161 -0
  71. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  72. data/test/dummy/config/locales/en.yml +23 -0
  73. data/test/dummy/config/locales/simple_form.en.yml +31 -0
  74. data/test/dummy/config/routes.rb +58 -0
  75. data/test/dummy/db/migrate/20140107210825_create_articles.rb +12 -0
  76. data/test/dummy/db/schema.rb +25 -0
  77. data/test/dummy/lib/assets/.keep +0 -0
  78. data/test/dummy/lib/templates/erb/scaffold/_form.html.erb +13 -0
  79. data/test/dummy/log/.keep +0 -0
  80. data/test/dummy/public/404.html +58 -0
  81. data/test/dummy/public/422.html +58 -0
  82. data/test/dummy/public/500.html +57 -0
  83. data/test/dummy/public/favicon.ico +0 -0
  84. data/test/dummy/test/fixtures/articles.yml +11 -0
  85. data/test/dummy/test/helpers/articles_helper_test.rb +4 -0
  86. data/test/dummy/test/models/article_test.rb +7 -0
  87. data/test/form_translation_test.rb +7 -0
  88. data/test/integration/navigation_test.rb +10 -0
  89. data/test/lib/form_translation/active_record_test.rb +12 -0
  90. data/test/lib/form_translation/custom_form_builder_test.rb +117 -0
  91. data/test/test_helper.rb +15 -0
  92. metadata +268 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 353ea97f8b6fd74b339836ee6ed39e92ba380218
4
+ data.tar.gz: b3475b5d28a56fc1cf45f65323f0c34ca6fdc6bc
5
+ SHA512:
6
+ metadata.gz: ac6386bb7109c47ccadee963145a211557cf2388b7dd4be27648c4e99e5a255299470f3ea45483f635a740ddd1d81906fc5751da9a1904dd68e191bc79c43791
7
+ data.tar.gz: 2c187a1d4696ba30842d08830449dda1da234c0d64a6e12633b5bbc35e798730bddc1d746fad75b308fb6dab3f43e2803e4b3faed5a9af43d59d41e15d5883b9
@@ -0,0 +1,9 @@
1
+ .bundle/
2
+ log/*.log
3
+ pkg/
4
+ test/dummy/db/*.sqlite3
5
+ test/dummy/db/*.sqlite3-journal
6
+ test/dummy/log/*.log
7
+ test/dummy/tmp/
8
+ test/dummy/.sass-cache
9
+ Gemfile.lock
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - '2.0.0'
4
+ - '2.1.0'
5
+ before_script: "bundle exec rake db:migrate RAILS_ENV=test"
6
+ script: "bundle exec rake test"
7
+
data/Gemfile ADDED
@@ -0,0 +1,22 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Declare your gem's dependencies in form_translation.gemspec.
4
+ # Bundler will treat runtime dependencies like base dependencies, and
5
+ # development dependencies will be added by default to the :development group.
6
+ gemspec
7
+
8
+ # Declare any dependencies that are still in development here instead of in
9
+ # your gemspec. These might include edge Rails or gems from your path or
10
+ # Git. Remember to move these dependencies to your gemspec before releasing
11
+ # your gem to rubygems.org.
12
+
13
+ # To use debugger
14
+ # gem 'debugger'
15
+ gem 'jquery-rails'
16
+ gem 'sass-rails', '~> 4.0.0'
17
+ gem 'bootstrap-sass', '~> 3.0.3.0'
18
+
19
+ group :development do
20
+ gem "better_errors"
21
+ gem "binding_of_caller"
22
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Florian Thomas
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.
@@ -0,0 +1,71 @@
1
+ # FormTranslation
2
+ [![Code Climate](https://codeclimate.com/github/Crunch09/form_translation.png)](https://codeclimate.com/github/Crunch09/form_translation)
3
+ [![Build Status](https://travis-ci.org/Crunch09/form_translation.png?branch=master)](https://travis-ci.org/Crunch09/form_translation)
4
+ **Not ready, don't use it in production yet.**
5
+
6
+ It uses `ActiveRecord::Store` to store language specific values and adds
7
+ tabs to your forms for each language.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'form_translation', github: 'Crunch09/form_translation'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ ```
20
+ $ bundle
21
+ $ rails g form_translation:install
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ * In your model include `FormTranslation::ForModel* and specify which attributes
27
+ should be translated.
28
+ ```ruby
29
+ class Article < ActiveRecord::Base
30
+ include FormTranslation::ForModel
31
+
32
+ translate_me :subject, :body
33
+ end
34
+ ```
35
+ * Within your `simple_form`-Form specify where to put your translation-tabs
36
+ with a `languagify` block.
37
+
38
+ ```erb
39
+ <%= simple_form_for(@article) do |f| %>
40
+ <div class="form-inputs">
41
+ <%= f.input :date %>
42
+ </div>
43
+ <div>
44
+ <%= f.languagify do |l| %>
45
+ <%= l.input :subject %>
46
+ <%= l.input :body %>
47
+ <% end %>
48
+ </div>
49
+ <div class="form-actions">
50
+ <%= f.button :submit %>
51
+ </div>
52
+ <% end %>
53
+ ```
54
+
55
+ Lastly, make sure to add the translated attributes to your permitted parameters
56
+ so they can be stored. The convention for the attribute name is as follows:
57
+ `language_shortname`_`attribute_name`
58
+
59
+ ```ruby
60
+ def article_params
61
+ params.require(:article).permit(:subject, :body, :de_subject, :de_body)
62
+ end
63
+ ```
64
+
65
+ ## Contributing
66
+
67
+ 1. Fork it
68
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
69
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
70
+ 4. Push to the branch (`git push origin my-new-feature`)
71
+ 5. Create new Pull Request
@@ -0,0 +1,34 @@
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 = 'FormTranslation'
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("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 4 gems installed from the root of your application.
3
+
4
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
5
+ ENGINE_PATH = File.expand_path('../../lib/form_translation/engine', __FILE__)
6
+
7
+ require 'rails/all'
8
+ require 'rails/engine/commands'
@@ -0,0 +1,2 @@
1
+ Rails.application.routes.draw do
2
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'form_translation/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "form_translation"
8
+ spec.version = FormTranslation::VERSION
9
+ spec.authors = ["Florian Thomas"]
10
+ spec.email = ["flo@florianthomas.net"]
11
+ spec.description = %q{Include fields for multiple languages in your forms.}
12
+ spec.summary = %q{Include fields for multiple languages in your forms.}
13
+ spec.homepage = "https://github.com/Crunch09/form_translation"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "sqlite3"
24
+ spec.add_dependency "rails", "~> 4.0.0"
25
+ spec.add_dependency "simple_form", "~> 3.1.0.rc1"
26
+ end
@@ -0,0 +1,26 @@
1
+ require "form_translation/version"
2
+ require "form_translation/engine"
3
+ require "form_translation/for_model"
4
+ require "form_translation/custom_form_builder"
5
+ require "form_translation/errors"
6
+ require "form_translation/active_record"
7
+
8
+ module FormTranslation
9
+
10
+ mattr_accessor :default_language
11
+ @@default_language = :de
12
+
13
+ mattr_accessor :foreign_languages
14
+ @@foreign_languages = [:en]
15
+
16
+ mattr_accessor :translation_column
17
+ @@translation_column = :translation
18
+
19
+ def self.config
20
+ yield self
21
+ end
22
+
23
+ def self.languages
24
+ (Array(self.default_language) + Array(self.foreign_languages)).uniq
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ module FormTranslation::SwitchLocale
2
+ extend ActiveSupport::Concern
3
+
4
+ def with_locale(loc, &block)
5
+ self.class.with_locale(loc, &block)
6
+ end
7
+
8
+ included do
9
+ @@_form_translation_locale = nil
10
+ end
11
+
12
+ module ClassMethods
13
+ def with_locale(loc, &block)
14
+ raise "unsupported language #{loc}" unless FormTranslation.languages.member? loc
15
+ t = self.class_variable_get(:@@_form_translation_locale)
16
+ @@_form_translation_locale = loc
17
+ yield
18
+ @@_form_translation_locale = t
19
+ end
20
+
21
+ def form_translation_locale
22
+ @@_form_translation_locale ||= nil
23
+ end
24
+ end
25
+ end
26
+
27
+ ActiveRecord::Base.send :include, FormTranslation::SwitchLocale
@@ -0,0 +1,22 @@
1
+ require 'simple_form'
2
+ require 'simple_form/form_builder'
3
+ require 'form_translation/languages_form_builder'
4
+
5
+ module FormTranslation
6
+ class CustomFormBuilder < SimpleForm::FormBuilder
7
+
8
+ def languagify &block
9
+ return unless block_given?
10
+ LanguagesFormBuilder.new(self).render &block
11
+ end
12
+ end
13
+
14
+ begin
15
+ require 'nested_form/builder_mixin'
16
+ class NestedCustomFormBuilder < CustomFormBuilder
17
+ include ::NestedForm::BuilderMixin
18
+ end
19
+ rescue LoadError
20
+ end
21
+ end
22
+
@@ -0,0 +1,10 @@
1
+ module FormTranslation
2
+ class Engine < ::Rails::Engine
3
+ initializer 'form_translation' do |app|
4
+ ActiveSupport.on_load(:action_view) do
5
+ require 'form_translation/view_helper'
6
+ ActionView::Base.send(:include, FormTranslation::ViewHelper)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ module FormTranslation
2
+ module Errors
3
+ class InvalidColumnException < StandardError; end
4
+ end
5
+ end
@@ -0,0 +1,76 @@
1
+ module FormTranslation
2
+ module ForModel
3
+ def values_given_for? lng
4
+ self.class.translated_attrs.each do |a|
5
+ begin
6
+ result = send "#{lng}_#{a}"
7
+ rescue
8
+ raise FormTranslation::Errors::InvalidColumnException,
9
+ 'You need to specify an existing and valid column to store your translations in.'
10
+ end
11
+ return true if result.present?
12
+ end
13
+ false
14
+ end
15
+
16
+ def translate! language = I18n.locale
17
+ unless language == FormTranslation.default_language
18
+ self.class.translated_attrs.each do |a|
19
+ send "#{a}=", send("#{language}_#{a}")
20
+ end
21
+ end
22
+ end
23
+
24
+ def self.included(base)
25
+ base.extend ClassMethods
26
+ end
27
+
28
+ module ClassMethods
29
+ def translate_me *methods
30
+ store FormTranslation.translation_column
31
+ methods.each do |m|
32
+ FormTranslation.foreign_languages.each do |l|
33
+ store_accessor FormTranslation.translation_column, "#{l}_#{m}".to_sym
34
+ end
35
+ end
36
+
37
+ self.class.class_exec do
38
+ define_method :translated_attrs do
39
+ methods
40
+ end
41
+
42
+ define_method :form_translations do
43
+ FormTranslation.foreign_languages.collect do |f|
44
+ methods.collect do |m|
45
+ "#{f}_#{m}".to_sym
46
+ end
47
+ end.flatten
48
+ end
49
+ end
50
+ create_translated_getters(methods)
51
+ end # translate_me
52
+
53
+ def create_translated_getters(methods)
54
+ mod = Module.new
55
+ methods.each do |nam|
56
+ mod.send(:define_method, nam) do
57
+ return super() unless self.class.form_translation_locale
58
+ return super() if self.class.form_translation_locale == FormTranslation.default_language
59
+ a = self.send "#{self.class.form_translation_locale}_#{nam}"
60
+ a.presence || self[nam]
61
+ end # define_method
62
+ end #methods.each
63
+
64
+ prepend mod
65
+ end # create_translated_getters
66
+
67
+ def translation_names_for *attributes
68
+ Array(attributes).flatten.collect do |a|
69
+ FormTranslation.foreign_languages.collect do |f|
70
+ "#{f}_#{a}".to_sym
71
+ end
72
+ end.flatten
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,73 @@
1
+ module FormTranslation
2
+ class LanguagesFormBuilder
3
+
4
+ attr_accessor :form_builder, :language
5
+ delegate :object, :template, :find_wrapper, to: :form_builder
6
+
7
+ def initialize(form_builder)
8
+ @form_builder = form_builder
9
+ end
10
+
11
+ def render(&block)
12
+ rnd = SecureRandom.hex(8)
13
+ template.content_tag(:div, '') do
14
+ divs = ''
15
+ divs += template.content_tag(:ul, class: 'nav nav-tabs') do
16
+ li_content rnd
17
+ end
18
+ divs += template.content_tag(:div, class: 'tab-content') do
19
+ language_tabs rnd, &block
20
+ end
21
+ divs.html_safe
22
+ end
23
+ end
24
+
25
+
26
+ def association(*args)
27
+ raise "not implemented!"
28
+ end
29
+
30
+ def input(attribute_name, options={}, &block)
31
+ # @language is set and not default.
32
+ options = @defaults.deep_dup.deep_merge(options) if @defaults
33
+ input = form_builder.send(:find_input, attribute_name, options, &block)
34
+ input.instance_variable_set("@attribute_name", "#{self.language}_#{input.attribute_name}".to_sym)
35
+
36
+ chosen =
37
+ if name = options[:wrapper] || form_builder.send(:find_wrapper_mapping, input.input_type)
38
+ name.respond_to?(:render) ? name : SimpleForm.wrapper(name)
39
+ else
40
+ form_builder.wrapper
41
+ end
42
+
43
+ chosen.render input
44
+ end
45
+
46
+ private
47
+
48
+ def li_content rnd
49
+ FormTranslation.languages.collect do |l|
50
+ listyle = 'empty_tab' if l != FormTranslation.default_language && !object.values_given_for?(l)
51
+ listyle = 'active' if l == FormTranslation.default_language
52
+
53
+ template.content_tag(:li, class: (listyle || '')) do
54
+ template.link_to(l, "##{l}_#{rnd}", data: {toggle: 'tab'})
55
+ end
56
+ end.join.html_safe
57
+ end
58
+
59
+ def language_tabs rnd
60
+ FormTranslation.languages.collect do |l|
61
+ @language = l
62
+ active = 'active' if l == FormTranslation.default_language
63
+ template.content_tag(:div, class: "tab-pane #{active}", id: "#{l}_#{rnd}") do
64
+ if l == FormTranslation.default_language
65
+ yield form_builder
66
+ else
67
+ yield self
68
+ end
69
+ end
70
+ end.join.html_safe
71
+ end
72
+ end
73
+ end