form_translation 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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