refinerycms-translations 0.3

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Victor Castell
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,61 @@
1
+ ## RefineryCMS-Translation ##
2
+
3
+ A simple approach to content translation for [RefineryCMS](http://refinerycms.org).
4
+
5
+ Features:
6
+
7
+ * Mark string or block as translatable in you view, key-value * locale.
8
+ * Let the end-user translate from Refinery backend
9
+ * On the first request that need translation, locale for every language is created
10
+ * You can define translated string to be edited with text_field or WYMeditor in the backend.
11
+ * Translation are cached
12
+ * When the content change, the translation is marked as out-dated to ease site maintenance.
13
+
14
+ ### Install ###
15
+
16
+ Install the plugin
17
+
18
+ Add this line to your Gemfile:
19
+ > gem 'refinerycms-translations', :git => 'git@github.com:seasonlabs/refinerycms-translations.git'
20
+
21
+ Install the gem
22
+ > bundle install
23
+
24
+ Copy the migration file
25
+ > rails generate refinerycms_pepes
26
+
27
+ Run the migration
28
+
29
+ > rake db:migrate
30
+
31
+ Make sure you have correctly set the following setting in Refinery: 'i18n_frontend_translation_locales', 'i18n_translation_default_frontend_locale'
32
+
33
+ ### Usage ###
34
+
35
+ Given the following code in you view:
36
+
37
+ > <h1><%= RefinerySetting.site_name %></h1>
38
+
39
+ You can do:
40
+
41
+ > <h1><%= Translation.for_string('site name', RefinerySetting.site_name) %></h1>
42
+
43
+ Or for more complex text:
44
+
45
+ > <div id='footer'>
46
+ > <p>Please give us a call! 1-877-555-1234</p>
47
+ > <p>Copyright 2010 - Your Company Name</p>
48
+ > </div>
49
+
50
+ Using a block:
51
+
52
+ > <div id='footer'>
53
+ > <% Translate.for_block('footer') do %>
54
+ > <p>Please give us a call! 1-877-555-1234</p>
55
+ > <p>Copyright 2010 - Your Company Name</p>
56
+ > <% end %>
57
+ > </div>
58
+
59
+ Note: for_string and for_block both take the option "wym" argument to edit the translation with the WYM editor. for_block default to true, for_string default to false.
60
+
61
+ Based on code from http://github.com/unixcharles
@@ -0,0 +1,16 @@
1
+ class Admin::TranslationsController < Admin::BaseController
2
+
3
+ crudify :translation, :title_attribute => :name, :order => "fresh, updated_at DESC, name ASC"
4
+
5
+ private
6
+ def paginate_all_translations
7
+ if params[:language]
8
+ @translations = Translation.paginate :page => params[:page],
9
+ :order => "fresh, updated_at DESC, name ASC",
10
+ :conditions => {:locale => params[:language]}
11
+ else
12
+ @translations = Translation.paginate :page => params[:page],
13
+ :order => "fresh, updated_at DESC, name ASC"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,30 @@
1
+ class TranslationsController < ApplicationController
2
+
3
+ before_filter :find_all_translations
4
+ before_filter :find_page
5
+
6
+ def index
7
+ # you can use meta fields from your model instead (e.g. browser_title)
8
+ # by swapping @page for @translations in the line below:
9
+ present(@page)
10
+ end
11
+
12
+ def show
13
+ @translations = Translations.find(params[:id])
14
+
15
+ # you can use meta fields from your model instead (e.g. browser_title)
16
+ # by swapping @page for @translations in the line below:
17
+ present(@page)
18
+ end
19
+
20
+ protected
21
+
22
+ def find_all_translations
23
+ @translations = Translations.find(:all, :order => "position ASC")
24
+ end
25
+
26
+ def find_page
27
+ @page = Page.find_by_link_url("/translations")
28
+ end
29
+
30
+ end
@@ -0,0 +1,72 @@
1
+ class Translation < ActiveRecord::Base
2
+
3
+ acts_as_indexed :fields => [:name]
4
+
5
+ validates_presence_of :name
6
+
7
+ before_update { |record| Translation.cache_expire(record.name, record.locale, record.untranslated_was) }
8
+ after_save { |record| Translation.cache_write(record.name, record.locale, record.untranslated, record.value) }
9
+
10
+ # will_paginate per_page
11
+ def self.per_page
12
+ 20
13
+ end
14
+
15
+ # Caching methods
16
+ def self.cache_key(name, locale, untranslated)
17
+ "#{Refinery.base_cache_key}_translation_#{name}_#{locale.to_s}_#{Digest::MD5.hexdigest(untranslated)}"
18
+ end
19
+
20
+ def self.cache_read(name, locale, untranslated)
21
+ Rails.cache.read(cache_key(name, locale, untranslated))
22
+ end
23
+
24
+ def self.cache_expire(name, locale, untranslated)
25
+ Rails.cache.read(cache_key(name, locale, untranslated), nil)
26
+ end
27
+
28
+ def self.cache_write(name, locale, untranslated, value)
29
+ Rails.cache.write(cache_key(name, locale, untranslated), value)
30
+ end
31
+
32
+ def self.for_block(name, wym = true)
33
+ self.lookup(name, yield, wym)
34
+ end
35
+
36
+ def self.for_string(name, untranslated, wym = false)
37
+ self.lookup(name, untranslated, wym)
38
+ end
39
+
40
+ def self.lookup(name, untranslated = nil, wym = false)
41
+ locale = I18n.locale
42
+ return untranslated if locale == Refinery::I18n.default_locale
43
+
44
+ if translation = self.cache_read(name,locale,untranslated)
45
+ return translation
46
+ end if RefinerySetting.find_or_set(:i18n_frontend_cache_translation, true, {:scoping => 'refinery'})
47
+
48
+ if ( translation = self.find(:first, :conditions => {:name => name.to_s, :locale => locale.to_s}) ).nil?
49
+ (Refinery::I18n.locales.keys - [Refinery::I18n.default_frontend_locale]).each do |current_locale|
50
+ if (translation = self.find(:first, :conditions => {:name => name, :locale => current_locale.to_s})).nil?
51
+ Translation.create(:name => name, :locale => current_locale.to_s,
52
+ :value => untranslated, :untranslated => untranslated,:wym => wym,
53
+ :fresh => false, :freshness_key => Digest::MD5.hexdigest(untranslated))
54
+ end
55
+ end
56
+ translation = self.find(:first, :conditions => {:name => name.to_s, :locale => locale.to_s})
57
+ else
58
+ if translation.fresh
59
+ unless translation.freshness_key == Digest::MD5.hexdigest(untranslated)
60
+ translation.freshness_key = Digest::MD5.hexdigest(untranslated)
61
+ translation.untranslated = untranslated
62
+ translation.fresh = false
63
+ translation.save
64
+ end
65
+ end
66
+ end
67
+
68
+ self.cache_write(name, locale, untranslated, translation.value) if RefinerySetting.find_or_set(:i18n_frontend_cache_translation, true, {:scoping => 'refinery'})
69
+ translation.value
70
+ end
71
+
72
+ end
@@ -0,0 +1,32 @@
1
+ <% form_for [:admin, @translation] do |f| -%>
2
+ <h2>
3
+ <%=t(".translating_key_from_default_to",
4
+ :key => @translation.name.titleize,
5
+ :from => Refinery::I18n.locales[Refinery::I18n.default_locale],
6
+ :to => Refinery::I18n.locales[@translation.locale]) %>
7
+ </h2>
8
+ <div class='field'>
9
+ <%= f.label :untranslated, t('.untranslated') -%>
10
+ <% if @translation.wym %>
11
+ <%= sanitize @translation.untranslated, :tags => %w(p br), :attributes => [nil] %>
12
+ <% else %>
13
+ <p><%= sanitize @translation.untranslated, :tags => [nil], :attributes => [nil] %></p>
14
+ <% end %>
15
+ </div>
16
+
17
+ <div class='field'>
18
+ <%= f.label :value, t('.value') -%>
19
+ <% if @translation.wym %>
20
+ <%= f.text_area :value, :rows => 20, :class => "wymeditor widest" -%>
21
+ <% else %>
22
+ <%= f.text_field :value -%>
23
+ <% end %>
24
+ </div>
25
+
26
+ <div class='field'>
27
+ <%= f.label :fresh, t('.fresh') -%>
28
+ <%= f.check_box :fresh -%>
29
+ </div>
30
+
31
+ <%= render :partial => "/shared/admin/form_actions", :locals => {:f => f, :continue_editing => false} %>
32
+ <% end -%>
@@ -0,0 +1,4 @@
1
+ <ul id='sortable_list'>
2
+ <%= render :partial => 'translations', :collection => @translations %>
3
+ </ul>
4
+ <%= render :partial => "/shared/admin/sortable_list", :locals => {:continue_reordering => (defined?(continue_reordering) ? continue_reordering : true)} %>
@@ -0,0 +1,19 @@
1
+ <li class='clearfix record <%= cycle("on", "on-hover") %>' id="<%= dom_id(translation) -%>">
2
+ <span class='title'>
3
+ <%= image_tag("/images/refinery/icons/flags/#{translation.locale}.png") unless params[:language] %>
4
+ <%=h translation.name.titleize %>
5
+ <%= content_tag(:strong, t(".not_fresh")) unless translation.fresh %>
6
+ <span class="preview">&nbsp;</span>
7
+ </span>
8
+ <span class='actions'>
9
+ <%= link_to refinery_icon_tag("application_edit.png"), edit_admin_translation_path(translation),
10
+ :title => t('.edit') %>
11
+ <%= link_to refinery_icon_tag("delete.png"), admin_translation_path(translation),
12
+ :class => "cancel confirm-delete",
13
+ :title => t('.delete'),
14
+ :'data-confirm' => t('shared.admin.delete.message',
15
+ :title => translation.name
16
+ ),
17
+ :'data-method' => :delete %>
18
+ </span>
19
+ </li>
@@ -0,0 +1 @@
1
+ <%= render :partial => "form" %>
@@ -0,0 +1,68 @@
1
+ <div id='actions'>
2
+ <ul>
3
+ <li>
4
+ <%= render :partial => "/shared/admin/search", :locals => {:url => admin_translations_url} %>
5
+ </li>
6
+ <% if !searching? and Translation.count > 1 %>
7
+ <li>
8
+ <%= link_to t('refinery.reorder', :what => "Translations"), admin_translations_url, :id => "reorder_action", :class => "reorder_icon" %>
9
+ <%= link_to t('refinery.reorder_done', :what => "Translations"), admin_translations_url, :id => "reorder_action_done", :style => "display: none;", :class => "reorder_icon" %>
10
+ </li>
11
+ <% end %>
12
+ </ul>
13
+
14
+ <% current_locale = params[:language] -%>
15
+ <ul id='current_locale'>
16
+ <li>
17
+ <% if current_locale %>
18
+ <%= link_to "#{Refinery::I18n::locales[current_locale]}
19
+ <span>#{t('.change_language')}</span>
20
+ <span style='display:none;'>#{t('shared.admin.form_actions.cancel')}</span>".html_safe,
21
+ "#",
22
+ :style => "background-image: url('/images/refinery/icons/flags/#{current_locale}.png');" %>
23
+ <% else %>
24
+ <%= link_to "#{t('.all_language')}<span>#{t('.change_language')}</span><span style='display:none;'> #{t('shared.admin.form_actions.cancel')}</span>".html_safe,
25
+ "#",
26
+ :style => "background-image: url('/images/refinery/icons/flags/en.png');" %>
27
+
28
+ <% end %>
29
+ </li>
30
+ </ul>
31
+ <ul id='other_locales' style='display: none'>
32
+ <% (Refinery::I18n.locales.keys - [Refinery::I18n.default_frontend_locale]).each do |locale| %>
33
+ <li>
34
+ <%= link_to Refinery::I18n.locales[locale],
35
+ params.dup.tap { |p| p[:language] = locale },
36
+ :style => "background-image: url('/images/refinery/icons/flags/#{locale}.png');" %>
37
+ </li>
38
+ <% end %>
39
+ </ul>
40
+
41
+ </div>
42
+ <div id='records'>
43
+ <% if params[:language] %>
44
+ <h2><%= t('.language', :language => Refinery::I18n.locales[params[:language]]) %></h2>
45
+ <% end %>
46
+ <% if searching? %>
47
+ <h2><%= t('admin.search_results_for', :query => params[:search]) %></h2>
48
+ <% if @translations.any? %>
49
+ <%= render :partial => "translation", :collection => @translations %>
50
+ <% else %>
51
+ <p><%= t('admin.search_no_results') %></p>
52
+ <% end %>
53
+ <% else %>
54
+ <% if @translations.any? %>
55
+ <%= will_paginate @translations, :previous_label => '&laquo;', :next_label => '&raquo;' %>
56
+ <ul id='sortable_list'>
57
+ <%= render :partial => 'translation', :collection => @translations %>
58
+ </ul>
59
+ <%= will_paginate @translations, :previous_label => '&laquo;', :next_label => '&raquo;' %>
60
+ <% else %>
61
+ <p>
62
+ <strong>
63
+ <%= t('.no_items_yet') %>
64
+ </strong>
65
+ </p>
66
+ <% end %>
67
+ <% end %>
68
+ </div>
@@ -0,0 +1 @@
1
+ <%= render :partial => "form" %>
@@ -0,0 +1,11 @@
1
+ <% content_for :body_content_left do %>
2
+ <ul id="translations">
3
+ <% @translations.each do |translations| %>
4
+ <li>
5
+ <%= link_to translations.name, translations_url(translations) %>
6
+ </li>
7
+ <% end %>
8
+ </ul>
9
+ <% end %>
10
+
11
+ <%= render :partial => "/shared/content_page" %>
@@ -0,0 +1,30 @@
1
+ <% content_for :body_content_title do %>
2
+ <%= @translations.name %>
3
+ <% end %>
4
+
5
+ <% content_for :body_content_left do %>
6
+
7
+ <div>
8
+ <h3>Name</h3>
9
+ <%=raw @translations.name %>
10
+ </div>
11
+
12
+ <div>
13
+ <h3>Value</h3>
14
+ <%=raw @translations.value %>
15
+ </div>
16
+
17
+ <% end %>
18
+
19
+ <% content_for :body_content_right do %>
20
+ <h2><%= t('.other') %></h2>
21
+ <ul id="translations">
22
+ <% @translations.each do |translations| %>
23
+ <li>
24
+ <%= link_to translations.name, translations_url(translations) %>
25
+ </li>
26
+ <% end %>
27
+ </ul>
28
+ <% end %>
29
+
30
+ <%= render :partial => "/shared/content_page" %>
@@ -0,0 +1,28 @@
1
+ en:
2
+ plugins:
3
+ translations:
4
+ title: Translations
5
+ admin:
6
+ translations:
7
+ index:
8
+ create_new: Create a new Translation
9
+ reorder: Reorder Translations
10
+ reorder_done: Done Reordering Translations
11
+ sorry_no_results: Sorry! There are no results found.
12
+ no_items_yet: There are no translations yet. Click "Create a new Translation" to add your first translation.
13
+ change_language: Select the language to translate.
14
+ all_language: All
15
+ language: "Translations for '{{language}}'"
16
+ singular_name:
17
+ view_live: View this translation live <br/><em>(opens in a new window)</em>
18
+ edit: Edit this translation
19
+ delete: Remove this translation forever
20
+ form:
21
+ fresh: "Mark this translation as fresh when you're done"
22
+ translating_key_from_default_to: "Translate '{{key}}' from '{{from}}' to '{{to}}'"
23
+ untranslated: "Untranslated content"
24
+ value: "You're translation"
25
+ translation:
26
+ edit: Edit this translation
27
+ delete: Delete this translation
28
+ not_fresh: Need update
data/config/routes.rb ADDED
@@ -0,0 +1,17 @@
1
+ #Refinery::Application.routes.draw do
2
+ # resources :translations
3
+
4
+ # scope(:path => 'refinery', :as => 'admin', :module => 'admin') do
5
+ # resources :translations do
6
+ # collection do
7
+ # post :update_positions
8
+ # end
9
+ # end
10
+ # end
11
+ #end
12
+
13
+ ActionController::Routing::Routes.draw do |map|
14
+ map.namespace(:admin, :path_prefix => 'refinery') do |admin|
15
+ admin.resources :translations
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ class RefinerycmsTranslations < Refinery::Generators::EngineInstaller
2
+
3
+ source_root File.expand_path('../../', __FILE__)
4
+ engine_name "translations"
5
+
6
+ end
@@ -0,0 +1,13 @@
1
+ namespace :refinery do
2
+
3
+ namespace :translations do
4
+
5
+ # call this task my running: rake refinery:translations:my_task
6
+ # desc "Description of my task below"
7
+ # task :my_task => :environment do
8
+ # # add your logic here
9
+ # end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,20 @@
1
+ require 'refinery'
2
+
3
+ module Refinery
4
+ module Translations
5
+ class Engine < Rails::Engine
6
+ initializer "static assets" do |app|
7
+ app.middleware.insert_after ::ActionDispatch::Static, ::ActionDispatch::Static, "#{root}/public"
8
+ end
9
+
10
+ config.after_initialize do
11
+ Refinery::Plugin.register do |plugin|
12
+ plugin.name = "translations"
13
+ plugin.activity = {:class => Translations,
14
+ :title => 'name'
15
+ }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'refinerycms-translationsgem'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestRefinerycmsTranslationsgem < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: refinerycms-translations
3
+ version: !ruby/object:Gem::Version
4
+ hash: 13
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 3
9
+ version: "0.3"
10
+ platform: ruby
11
+ authors:
12
+ - season
13
+ - Victor Castell
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-20 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: thoughtbot-shoulda
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ description: Ruby on Rails Translations engine for Refinery CMS rails 3 compatible
36
+ email: victorcoder@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - LICENSE
43
+ - README.rdoc
44
+ files:
45
+ - app/controllers/admin/translations_controller.rb
46
+ - app/controllers/translations_controller.rb.txt
47
+ - app/models/translation.rb
48
+ - app/views/admin/translations/_form.html.erb
49
+ - app/views/admin/translations/_sortable_list.html.erb
50
+ - app/views/admin/translations/_translation.html.erb
51
+ - app/views/admin/translations/edit.html.erb
52
+ - app/views/admin/translations/index.html.erb
53
+ - app/views/admin/translations/new.html.erb
54
+ - app/views/translations/index.html.erb
55
+ - app/views/translations/show.html.erb
56
+ - config/locales/en.yml
57
+ - config/routes.rb
58
+ - lib/generators/refinerycms_translations_generator.rb
59
+ - lib/tasks/translations.rake
60
+ - lib/translations.rb
61
+ - LICENSE
62
+ - README.rdoc
63
+ - test/helper.rb
64
+ - test/test_refinerycms-translations.rb
65
+ has_rdoc: true
66
+ homepage: http://github.com/seasonlabs/refinerycms-translations
67
+ licenses: []
68
+
69
+ post_install_message:
70
+ rdoc_options:
71
+ - --charset=UTF-8
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ hash: 3
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ requirements: []
93
+
94
+ rubyforge_project:
95
+ rubygems_version: 1.3.7
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: Ruby on Rails Translations engine for Refinery CMS
99
+ test_files:
100
+ - test/helper.rb
101
+ - test/test_refinerycms-translations.rb