couch_i18n 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2011 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = CouchI18n
2
+
3
+ This projects is created to make translations editable. It is created using
4
+ the simply_stored gem. To use the web frontend please read the README section
5
+ on this carefully. Important to know is that this system sits *on top* of the
6
+ standard YAML translation system. To import all yml translations to the CouchDB
7
+ database type:
8
+ CouchI18n::Store.import_from_yaml
9
+ Now all translations are ported to the database. If you change then now in the
10
+ yaml files, they will nolonger be displayed in the website. They should be managed
11
+ in the database. This gem also provides a translation management system. To place this
12
+ in your own design, create a file _config/initializers/couch_i18n.rb_ with the
13
+ following content:
14
+ CouchI18n::ApplicationController.layout 'application'
15
+ Your Gemfile should look like:
16
+ gem 'couch_i18n'
17
+ gem 'kaminari'
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+
8
+ require 'rake/rdoctask'
9
+
10
+ Rake::RDocTask.new(:rdoc) do |rdoc|
11
+ rdoc.rdoc_dir = 'rdoc'
12
+ rdoc.title = 'CouchI18n'
13
+ rdoc.options << '--line-numbers' << '--inline-source'
14
+ rdoc.rdoc_files.include('README.rdoc')
15
+ rdoc.rdoc_files.include('lib/**/*.rb')
16
+ end
17
+
18
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
19
+ load 'rails/tasks/engine.rake'
20
+
21
+ require 'rake/testtask'
22
+
23
+ Rake::TestTask.new(:test) do |t|
24
+ t.libs << 'lib'
25
+ t.libs << 'test'
26
+ t.pattern = 'test/**/*_test.rb'
27
+ t.verbose = false
28
+ end
29
+
30
+
31
+ task :default => :test
@@ -0,0 +1,11 @@
1
+ // This is a manifest file that'll be compiled into including all the files listed below.
2
+ // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
3
+ // be included in the compiled file accessible from http://example.com/assets/application.js
4
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
+ // the compiled file.
6
+ //
7
+ <% unless options[:skip_javascript] -%>
8
+ //= require <%= options[:javascript] %>
9
+ //= require <%= options[:javascript] %>_ujs
10
+ <% end -%>
11
+ //= require_tree .
@@ -0,0 +1,7 @@
1
+ /*
2
+ * This is a manifest file that'll automatically include all the stylesheets available in this directory
3
+ * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
4
+ * the top of the compiled file, but it's generally better to create a new file per style scope.
5
+ *= require_self
6
+ *= require_tree .
7
+ */
@@ -0,0 +1,4 @@
1
+ module CouchI18n
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,60 @@
1
+ module CouchI18n
2
+ class StoresController < ApplicationController
3
+ def index
4
+ @available_higher_offsets = []
5
+ if params[:offset].present?
6
+ @levels = params[:offset].split('.')
7
+ # Add higher levels. Do not add the last level, since it is the current one => 0..-2
8
+ @levels[0..-2].each_with_index do |level_name, i|
9
+ @available_higher_offsets << {
10
+ :name => level_name,
11
+ :offset => @levels[0..i].join('.')
12
+ }
13
+ end
14
+ @couch_i18n_stores = CouchI18n::Store.find_all_by_key(params[:offset]..(params[:offset] + '\u9999'), :page => params[:page], :per_page => 30)
15
+ @available_deeper_offsets = CouchI18n::Store.get_keys_by_level(@levels.size, :startkey => @levels, :endkey => @levels + [{}]).
16
+ map{|dl| {:name => dl, :offset => [params[:offset], dl].join('.')}}
17
+ else
18
+ @couch_i18n_stores = CouchI18n::Store.all(:page => params[:page], :per_page => 30)
19
+ @available_deeper_offsets = CouchI18n::Store.get_keys_by_level(0).
20
+ map{|dl| {:name => dl, :offset => dl}}
21
+ end
22
+ end
23
+
24
+ def show
25
+ @couch_i18n_store = CouchI18n::Store.find(params[:id])
26
+ end
27
+
28
+ def new
29
+ @couch_i18n_store = CouchI18n::Store.new :key => params[:offset]
30
+ end
31
+
32
+ def create
33
+ @couch_i18n_store = CouchI18n::Store.new params[:couch_i18n_store]
34
+ if @couch_i18n_store.save
35
+ redirect_to({:action => :index, :offset => @couch_i18n_store.key.to_s.sub(/\.\w+$/, '')}, :notice => I18n.t('action.create.successful', :model => CouchI18n::Store.model_name.human))
36
+ else
37
+ render :action => :new
38
+ end
39
+ end
40
+ def edit
41
+ @couch_i18n_store = CouchI18n::Store.find(params[:id])
42
+ end
43
+ def update
44
+ @couch_i18n_store = CouchI18n::Store.find(params[:id])
45
+ if @couch_i18n_store.update_attributes(params[:couch_i18n_store])
46
+ redirect_to({:action => :index, :offset => @couch_i18n_store.key.to_s.sub(/\.\w+$/, '')}, :notice => I18n.t('action.update.successful', :model => CouchI18n::Store.model_name.human))
47
+ else
48
+ render :action => :edit
49
+ end
50
+ end
51
+
52
+ def destroy
53
+ @couch_i18n_store = CouchI18n::Store.find(params[:id])
54
+ if @couch_i18n_store.destroy
55
+ flash[:notice] = I18n.t('action.destroy.successful', :model => CouchI18n::Store.model_name.human)
56
+ end
57
+ redirect_to({:action => :index, :offset => @couch_i18n_store.key.to_s.sub(/\.\w+$/, '')})
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,4 @@
1
+ module CouchI18n
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,12 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %title= defined?(site_title) ? site_title : I18n.t('couch_i18n.store.site_title')
5
+ = csrf_meta_tag
6
+ = yield :head
7
+ %body
8
+ #page-wrapper
9
+ #page-content
10
+ %h1= yield :title
11
+ = yield
12
+ #page-links= yield :page_links
@@ -0,0 +1,6 @@
1
+ module CouchI18n
2
+ class Engine < Rails::Engine
3
+ # Commented out be be used in rails < 3.1
4
+ #isolate_namespace CouchI18n
5
+ end
6
+ end
@@ -0,0 +1,63 @@
1
+ # First comment out backend declaration in config/initializers/i18n_backend.rb
2
+ # this looks like:
3
+ # #I18n.backend = I18n::Backend::Chain.new(I18n::Backend::KeyValue.new(CouchI18n::Store), I18n.backend)
4
+ # Then load the translations:
5
+ # I18n.t('New')
6
+ # Then create the translations
7
+ # I18n.t('New');I18n.backend.send(:translations).flatten_keys.each{|k, v| CouchI18n::Store.create(:key => k, :value => v)}
8
+ module CouchI18n
9
+ class Store
10
+ include SimplyStored::Couch
11
+ per_page_method :limit_value
12
+
13
+ property :key
14
+ property :value
15
+
16
+ validates_uniqueness_of :key
17
+
18
+ after_save :reload_i18n
19
+
20
+ view :all_documents, :key => :key
21
+ view :by_key, :key => :key
22
+
23
+ view :with_key_array, :map => %|function(doc){
24
+ if(doc.ruby_class && doc.ruby_class == 'CouchI18n::Store') {
25
+ emit(doc.key.split('.').slice(0,-1), 1);
26
+ }
27
+ }|, :type => :raw, :reduce => '_sum'
28
+
29
+ def self.available_locales
30
+ get_keys_by_level
31
+ end
32
+
33
+ def self.get_keys_by_level(level = 0, options = {})
34
+ data = database.view(with_key_array(options.merge(:group => true, :group_level => level.succ)))["rows"]
35
+ # data = data.select{|h| h["key"].size > level } # Only select ones that have a deeper nesting
36
+ data.map{|h| h['key'][level].try(:to_sym)}.compact
37
+ end
38
+
39
+ # Now the store features
40
+ def self.[]=(key, value, options = {})
41
+ key = key.to_s
42
+ existing = find_by_key(key) rescue nil
43
+ translation = existing || new(:key => key)
44
+ translation.value = value
45
+ translation.save
46
+ end
47
+
48
+ # alias for read
49
+ def self.[](key, options=nil)
50
+ find_by_key(key.to_s).try(:value) rescue nil
51
+ end
52
+
53
+ def self.keys
54
+ all.map(&:key)
55
+ end
56
+
57
+ private
58
+
59
+ def reload_i18n
60
+ I18n.reload!
61
+ end
62
+ end
63
+ end
data/lib/couch_i18n.rb ADDED
@@ -0,0 +1,32 @@
1
+ require "couch_i18n/engine"
2
+ require 'couch_i18n/store'
3
+ module CouchI18n
4
+ # This method imports yaml translations to the couchdb version. When run again new ones will
5
+ # be added. Translations already stored in the couchdb database are not overwritten
6
+ def self.import_from_yaml
7
+ raise "I18.backend not a I18n::Backend::Chain" unless I18n.backend.is_a?(I18n::Backend::Chain)
8
+ #
9
+ yml_backend = I18n.backend.backends.last
10
+ raise "Last backend not a I18n::Backend::Simple" unless yml_backend.is_a?(I18n::Backend::Simple)
11
+ yml_backend.load_translations
12
+ flattened_hash = traverse_flatten_keys({}, yml_backend.send(:translations))
13
+ flattened_hash.each do |key, value|
14
+ CouchI18n::Store.create :key => key, :value => value
15
+ end
16
+ end
17
+ private
18
+
19
+ # Recursive flattening.
20
+ def self.traverse_flatten_keys(store, obj, path = nil)
21
+ case obj
22
+ when Hash
23
+ obj.each{|k, v| traverse_flatten_keys(store, v, [path, k].compact.join('.'))}
24
+ when Array
25
+ store[path.underscore.tr(' ', '_')] = obj.to_json
26
+ #obj.each_with_index{|v, i| traverse_flatten_keys(store, v, [path, i].compact.join('.'))}
27
+ else
28
+ store[path.underscore.tr(' ', '_')] = obj
29
+ end
30
+ return store
31
+ end
32
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :couch_i18n do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: couch_i18n
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Benjamin ter Kuile
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-05-15 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: couch_i18n deliveres an in database storage for I18n translations, tested for rails
22
+ email: bterkuile@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - lib/couch_i18n/engine.rb
31
+ - lib/couch_i18n/store.rb
32
+ - lib/couch_i18n.rb
33
+ - lib/tasks/couch_i18n_tasks.rake
34
+ - app/controllers/couch_i18n/stores_controller.rb
35
+ - app/controllers/couch_i18n/application_controller.rb
36
+ - app/assets/javascripts/application.js
37
+ - app/assets/stylesheets/application.css
38
+ - app/helpers/couch_i18n/application_helper.rb
39
+ - app/views/layouts/couch_i18n/application.html.haml
40
+ - MIT-LICENSE
41
+ - Rakefile
42
+ - README.rdoc
43
+ has_rdoc: true
44
+ homepage: http://github.com/bterkuile/couch_i18n
45
+ licenses: []
46
+
47
+ post_install_message:
48
+ rdoc_options: []
49
+
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ segments:
64
+ - 0
65
+ version: "0"
66
+ requirements: []
67
+
68
+ rubyforge_project: couch_i18n
69
+ rubygems_version: 1.3.6
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: couch_i18n deliveres an in database storage for I18n translations, tested for rails
73
+ test_files: []
74
+