├── VERSION ├── spec ├── dummy │ ├── log │ │ └── .gitkeep │ ├── app │ │ ├── mailers │ │ │ └── .gitkeep │ │ ├── models │ │ │ ├── .gitkeep │ │ │ ├── article.rb │ │ │ └── admin_user.rb │ │ ├── assets │ │ │ ├── javascripts │ │ │ │ ├── active_admin.js │ │ │ │ ├── active_admin.js.coffee │ │ │ │ └── application.js │ │ │ └── stylesheets │ │ │ │ ├── application.css │ │ │ │ └── active_admin.css.scss │ │ ├── helpers │ │ │ └── application_helper.rb │ │ ├── controllers │ │ │ └── application_controller.rb │ │ ├── views │ │ │ └── layouts │ │ │ │ └── application.html.erb │ │ └── admin │ │ │ ├── admin_users.rb │ │ │ ├── articles.rb │ │ │ └── dashboard.rb │ ├── lib │ │ └── assets │ │ │ └── .gitkeep │ ├── public │ │ ├── favicon.ico │ │ ├── 500.html │ │ ├── 422.html │ │ └── 404.html │ ├── bin │ │ ├── rake │ │ ├── bundle │ │ └── rails │ ├── config │ │ ├── routes.rb │ │ ├── initializers │ │ │ ├── session_store.rb │ │ │ ├── filter_parameter_logging.rb │ │ │ ├── mime_types.rb │ │ │ ├── backtrace_silencers.rb │ │ │ ├── wrap_parameters.rb │ │ │ ├── secret_token.rb │ │ │ ├── inflections.rb │ │ │ ├── active_admin.rb │ │ │ └── devise.rb │ │ ├── environment.rb │ │ ├── boot.rb │ │ ├── database.yml │ │ ├── locales │ │ │ ├── en.yml │ │ │ └── devise.en.yml │ │ ├── application.rb │ │ └── environments │ │ │ ├── development.rb │ │ │ ├── test.rb │ │ │ └── production.rb │ ├── config.ru │ ├── db │ │ ├── migrate │ │ │ ├── 20140611144058_create_articles.rb │ │ │ ├── 20140611153231_translate_articles.rb │ │ │ └── 20140611144346_devise_create_admin_users.rb │ │ └── schema.rb │ ├── Rakefile │ ├── script │ │ └── rails │ └── README.rdoc ├── support │ ├── factories │ │ ├── admin_users.rb │ │ └── articles.rb │ └── capybara_activeadmin_helpers.rb ├── models │ └── article_spec.rb ├── spec_helper.rb └── features │ └── article_composing_spec.rb ├── .rspec ├── lib ├── activeadmin-globalize.rb └── active_admin │ ├── globalize │ ├── version.rb │ ├── engine.rb │ ├── active_record_extension.rb │ ├── index_table_for_extension.rb │ ├── form_builder_extension.rb │ └── attributes_table_extension.rb │ ├── view_helpers │ └── flag_helper.rb │ └── globalize.rb ├── config ├── spring.rb └── locales │ ├── he.yml │ ├── hu.yml │ ├── ar.yml │ ├── es.yml │ ├── en.yml │ ├── pt-BR.yml │ ├── pt-PT.yml │ ├── it.yml │ └── de.yml ├── app └── assets │ ├── images │ └── active_admin │ │ └── flags.png │ ├── stylesheets │ └── active_admin │ │ ├── active_admin_globalize_mixins.sass │ │ ├── active_admin_globalize_flags.sass │ │ └── active_admin_globalize.sass │ └── javascripts │ └── active_admin │ └── active_admin_globalize.js.coffee ├── .gitignore ├── Appraisals ├── .travis.yml ├── Rakefile ├── gemfiles ├── rails4_2.gemfile ├── rails5_0.gemfile └── rails5_1.gemfile ├── MIT-LICENSE ├── activeadmin-globalize.gemspec ├── Gemfile └── README.md /VERSION: -------------------------------------------------------------------------------- 1 | 0.9.9 -------------------------------------------------------------------------------- /spec/dummy/log/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/app/mailers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/app/models/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/lib/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format progress 3 | -------------------------------------------------------------------------------- /lib/activeadmin-globalize.rb: -------------------------------------------------------------------------------- 1 | require 'active_admin/globalize' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/javascripts/active_admin.js: -------------------------------------------------------------------------------- 1 | //= require active_admin/base 2 | -------------------------------------------------------------------------------- /spec/dummy/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /config/spring.rb: -------------------------------------------------------------------------------- 1 | # Tell spring where the app is 2 | Spring.application_root = './spec/dummy' -------------------------------------------------------------------------------- /spec/dummy/app/assets/javascripts/active_admin.js.coffee: -------------------------------------------------------------------------------- 1 | #= require active_admin/base 2 | -------------------------------------------------------------------------------- /spec/dummy/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative '../config/boot' 3 | require 'rake' 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /lib/active_admin/globalize/version.rb: -------------------------------------------------------------------------------- 1 | module ActiveAdmin 2 | module Globalize 3 | VERSION = '1.0.0.pre' 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/assets/images/active_admin/flags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabn/activeadmin-globalize/HEAD/app/assets/images/active_admin/flags.png -------------------------------------------------------------------------------- /spec/dummy/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery 3 | end 4 | -------------------------------------------------------------------------------- /spec/dummy/bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /spec/dummy/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | 3 | devise_for :admin_users, ActiveAdmin::Devise.config 4 | ActiveAdmin.routes(self) 5 | 6 | end 7 | -------------------------------------------------------------------------------- /spec/dummy/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path('../../config/application', __FILE__) 3 | require_relative '../config/boot' 4 | require 'rails/commands' 5 | -------------------------------------------------------------------------------- /spec/dummy/app/models/article.rb: -------------------------------------------------------------------------------- 1 | class Article < ActiveRecord::Base 2 | # Translated fields with globalize and for active admin 3 | active_admin_translates :title, :body 4 | 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Dummy::Application 5 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Dummy::Application.config.session_store :cookie_store, key: '_dummy_session' 4 | -------------------------------------------------------------------------------- /spec/dummy/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the Rails application. 5 | Dummy::Application.initialize! 6 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /spec/dummy/config/boot.rb: -------------------------------------------------------------------------------- 1 | # Set up gems listed in the Gemfile. 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__) 3 | 4 | require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) 5 | 6 | $:.unshift File.expand_path('../../../../lib', __FILE__) -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle/ 2 | .bin 3 | 4 | # sqlite files 5 | *.sqlite3 6 | 7 | # tmp files 8 | tmp/ 9 | 10 | # ignore Gemfile.lock and other lockfiles 11 | *.lock 12 | 13 | # Dummy app ignored stuff 14 | spec/dummy/db/*.sqlite3 15 | spec/dummy/log/*.log 16 | spec/dummy/tmp/ -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140611144058_create_articles.rb: -------------------------------------------------------------------------------- 1 | class CreateArticles < ActiveRecord::Migration 2 | def change 3 | create_table :articles do |t| 4 | t.string :title 5 | t.text :body 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/factories/admin_users.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | 3 | factory :user, class: AdminUser do 4 | 5 | sequence(:email) { |n| "admin#{n}@example.com" } 6 | password { 'password' } 7 | password_confirmation { |u| u.password } 8 | 9 | end 10 | 11 | end 12 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140611153231_translate_articles.rb: -------------------------------------------------------------------------------- 1 | class TranslateArticles < ActiveRecord::Migration 2 | def up 3 | Article.create_translation_table! title: :string, body: {type: :text} 4 | end 5 | 6 | def down 7 | Article.drop_translation_table! 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/dummy/Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # Add your own tasks in files placed in lib/tasks ending in .rake, 3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 4 | 5 | require File.expand_path('../config/application', __FILE__) 6 | 7 | Dummy::Application.load_tasks 8 | -------------------------------------------------------------------------------- /spec/dummy/app/models/admin_user.rb: -------------------------------------------------------------------------------- 1 | class AdminUser < ActiveRecord::Base 2 | # Include default devise modules. Others available are: 3 | # :confirmable, :lockable, :timeoutable and :omniauthable 4 | devise :database_authenticatable, 5 | :recoverable, :rememberable, :trackable, :validatable 6 | end 7 | -------------------------------------------------------------------------------- /spec/dummy/script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | APP_PATH = File.expand_path('../../config/application', __FILE__) 5 | require File.expand_path('../../config/boot', __FILE__) 6 | require 'rails/commands' 7 | -------------------------------------------------------------------------------- /spec/dummy/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dummy 5 | <%= stylesheet_link_tag "application", :media => "all" %> 6 | <%= javascript_include_tag "application" %> 7 | <%= csrf_meta_tags %> 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Appraisals: -------------------------------------------------------------------------------- 1 | appraise 'rails4_2' do 2 | gem 'rails', '~> 4.2.9' 3 | gem 'globalize', '~> 5.0.0' 4 | end 5 | 6 | appraise 'rails5_0' do 7 | gem 'rails', '~> 4.2.9' 8 | gem 'globalize', '~> 5.0.0' 9 | end 10 | 11 | appraise 'rails5_1' do 12 | gem 'devise', '~> 4.3' 13 | gem 'rails', '~> 5.1.3' 14 | gem 'globalize', '~> 5.1.0.beta2' 15 | end 16 | -------------------------------------------------------------------------------- /lib/active_admin/globalize/engine.rb: -------------------------------------------------------------------------------- 1 | module ActiveAdmin 2 | module Globalize 3 | class Engine < ::Rails::Engine 4 | initializer "Active Admin precompile hook", group: :all do |app| 5 | app.config.assets.precompile += [ 6 | "active_admin/active_admin_globalize.css", 7 | "active_admin/active_admin_globalize.js" 8 | ] 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /config/locales/he.yml: -------------------------------------------------------------------------------- 1 | he: 2 | active_admin: 3 | globalize: 4 | translations: "תרגומים" 5 | language: 6 | de: "גרמנית" 7 | en: "אנגלית" 8 | es: "ספרדית" 9 | fr: "צרפתית" 10 | hu: "הונגרית" 11 | it: "איטלקית" 12 | pt-BR: "פורטוגזית" 13 | pt-PT: "פורטוגזית (פורטוגל)" 14 | tr: "טורקית" 15 | he: "עברית" 16 | ar: "ערבית" 17 | 18 | -------------------------------------------------------------------------------- /config/locales/hu.yml: -------------------------------------------------------------------------------- 1 | hu: 2 | active_admin: 3 | globalize: 4 | translations: "Fordítások" 5 | language: 6 | de: "Német" 7 | en: "Angol" 8 | es: "Spanyol" 9 | fr: "Francia" 10 | hu: "Magyar" 11 | it: "Olasz" 12 | pt-BR: "Portuguese" 13 | pt-PT: "Portuguese (Portugal)" 14 | tr: "Török" 15 | he: "Héber" 16 | ar: "Arab" 17 | 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: ruby 3 | # Limit ruby versions to currently supported versions to avoid a big build matrix 4 | rvm: 5 | - 2.2.7 6 | - 2.3.4 7 | - 2.4.1 8 | # Load database schema before rake 9 | before_script: bundle exec rake db:schema:load 10 | # Test on all supported rails versions 11 | gemfile: 12 | - gemfiles/rails4_2.gemfile 13 | - gemfiles/rails5_0.gemfile 14 | - gemfiles/rails5_1.gemfile 15 | -------------------------------------------------------------------------------- /config/locales/ar.yml: -------------------------------------------------------------------------------- 1 | ar: 2 | active_admin: 3 | globalize: 4 | translations: "ترجمة" 5 | language: 6 | de: "ألماني" 7 | en: "الإنجليزية" 8 | es: "الأسبانية" 9 | fr: "اللغة الفرنسية" 10 | hu: "الهنغارية" 11 | it: "الإيطالي" 12 | pt-BR: "البرتغالية" 13 | pt-PT: "البرتغالية (البرتغال)" 14 | tr: "اللغة التركية" 15 | he: "العبرية" 16 | 17 | -------------------------------------------------------------------------------- /config/locales/es.yml: -------------------------------------------------------------------------------- 1 | es: 2 | active_admin: 3 | globalize: 4 | translations: "Traducciones" 5 | language: 6 | de: "Alemán" 7 | en: "Inglés" 8 | es: "Español" 9 | fr: "Francés" 10 | hu: "Húngaro" 11 | it: "Italiano" 12 | pt-BR: "Portugués" 13 | pt-PT: "Portugués (Portugal)" 14 | tr: "Turco" 15 | he: "Hebreo" 16 | ar: "Arábica" 17 | 18 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | active_admin: 3 | globalize: 4 | translations: "Translations" 5 | language: 6 | de: "German" 7 | en: "English" 8 | es: "Spanish" 9 | fr: "French" 10 | hu: "Hungarian" 11 | it: "Italian" 12 | pt-BR: "Portuguese" 13 | pt-PT: "Portuguese (Portugal)" 14 | tr: "Turkish" 15 | he: "Hebrew" 16 | ar: "Arabic" 17 | 18 | -------------------------------------------------------------------------------- /config/locales/pt-BR.yml: -------------------------------------------------------------------------------- 1 | pt-BR: 2 | active_admin: 3 | globalize: 4 | translations: "Traduções" 5 | language: 6 | de: "Alemão" 7 | en: "Inglês" 8 | es: "Espanhol" 9 | fr: "Francês" 10 | hu: "Húngaro" 11 | it: "Italiano" 12 | pt-BR: "Português" 13 | pt-PT: "Português (Portugal)" 14 | tr: "Turco" 15 | he: "Hebraico" 16 | ar: "Árabe" 17 | 18 | -------------------------------------------------------------------------------- /config/locales/pt-PT.yml: -------------------------------------------------------------------------------- 1 | pt-PT: 2 | active_admin: 3 | globalize: 4 | translations: "Traduções" 5 | language: 6 | de: "Alemão" 7 | en: "Inglês" 8 | es: "Espanhol" 9 | fr: "Francês" 10 | hu: "Húngaro" 11 | it: "Italiano" 12 | pt-BR: "Português" 13 | pt-PT: "Português (Portugal)" 14 | tr: "Turco" 15 | he: "Hebraico" 16 | ar: "Árabe" 17 | 18 | -------------------------------------------------------------------------------- /config/locales/it.yml: -------------------------------------------------------------------------------- 1 | it: 2 | active_admin: 3 | globalize: 4 | translations: "Traduzioni" 5 | language: 6 | de: "Tedesco" 7 | en: "Inglese" 8 | es: "Spagnolo" 9 | fr: "Francese" 10 | hu: "Ungherese" 11 | it: "Italiano" 12 | pt-BR: "Portoghese" 13 | pt-PT: "Portoghese (Portogallo)" 14 | tr: "Turco" 15 | he: "Ebraico" 16 | ar: "Arabo" 17 | 18 | -------------------------------------------------------------------------------- /config/locales/de.yml: -------------------------------------------------------------------------------- 1 | de: 2 | active_admin: 3 | globalize: 4 | translations: "Übersetzungen" 5 | language: 6 | de: "Deutsch" 7 | en: "Englisch" 8 | es: "Spanisch" 9 | fr: "Fränzösisch" 10 | hu: "Ungarisch" 11 | it: "Italienisch" 12 | pt-BR: "Portugiesisch" 13 | pt-PT: "Portugiesisch (Portugal)" 14 | tr: "Türkisch" 15 | he: "Hebräisch" 16 | ar: "Arabisch" 17 | 18 | -------------------------------------------------------------------------------- /spec/dummy/app/admin/admin_users.rb: -------------------------------------------------------------------------------- 1 | ActiveAdmin.register AdminUser do 2 | index do 3 | column :email 4 | column :current_sign_in_at 5 | column :last_sign_in_at 6 | column :sign_in_count 7 | default_actions 8 | end 9 | 10 | filter :email 11 | 12 | form do |f| 13 | f.inputs "Admin Details" do 14 | f.input :email 15 | f.input :password 16 | f.input :password_confirmation 17 | end 18 | f.actions 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | require 'bundler/gem_tasks' 3 | 4 | begin 5 | require 'bundler/setup' 6 | rescue LoadError 7 | puts 'You must `gem install bundler` and `bundle install` to run rake tasks' 8 | end 9 | 10 | APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__) 11 | load 'rails/tasks/engine.rake' 12 | 13 | Bundler::GemHelper.install_tasks 14 | 15 | require 'rspec/core/rake_task' 16 | RSpec::Core::RakeTask.new(:spec) 17 | 18 | task default: %w(app:test:prepare spec) 19 | -------------------------------------------------------------------------------- /lib/active_admin/view_helpers/flag_helper.rb: -------------------------------------------------------------------------------- 1 | require 'active_admin/view_helpers' 2 | 3 | module ActiveAdmin 4 | module ViewHelpers 5 | module FlagHelper 6 | 7 | # Return an image tag with background of given locale 8 | def flag_icon(locale) 9 | content_tag :i, '', class: "flag flag-#{locale}", title: I18n.t("active_admin.globalize.language.#{locale}") 10 | end 11 | 12 | end 13 | 14 | # Register as ActiveAdmin view helper 15 | include FlagHelper 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/support/factories/articles.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :article do 5 | title 'Article title' 6 | body 'Article Body' 7 | 8 | factory :localized_article do 9 | 10 | after :create do |a| 11 | I18n.with_locale(:it) { a.update_attributes! title: 'Italian title', body: 'Italian Body' } 12 | I18n.with_locale(:hu) { a.update_attributes! body: 'Hungarian Body' } 13 | end 14 | 15 | end 16 | 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters) 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the top of the 9 | * compiled file, but it's generally better to create a new file per style scope. 10 | * 11 | *= require_self 12 | *= require_tree . 13 | */ 14 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/stylesheets/active_admin.css.scss: -------------------------------------------------------------------------------- 1 | // SASS variable overrides must be declared before loading up Active Admin's styles. 2 | // 3 | // To view the variables that Active Admin provides, take a look at 4 | // `app/assets/stylesheets/active_admin/mixins/_variables.css.scss` in the 5 | // Active Admin source. 6 | // 7 | // For example, to change the sidebar width: 8 | // $sidebar-width: 242px; 9 | 10 | // Active Admin's got SASS! 11 | @import "active_admin/mixins"; 12 | @import "active_admin/base"; 13 | 14 | // Overriding any non-variable SASS must be done after the fact. 15 | // For example, to change the default status-tag color: 16 | // 17 | // .status_tag { background: #6090DB; } 18 | -------------------------------------------------------------------------------- /spec/dummy/config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | development: 7 | adapter: sqlite3 8 | database: db/development.sqlite3 9 | pool: 5 10 | timeout: 5000 11 | 12 | # Warning: The database defined as "test" will be erased and 13 | # re-generated from your development database when you run "rake". 14 | # Do not set this db to the same as development or production. 15 | test: 16 | adapter: sqlite3 17 | database: db/test.sqlite3 18 | pool: 5 19 | timeout: 5000 20 | 21 | production: 22 | adapter: sqlite3 23 | database: db/production.sqlite3 24 | pool: 5 25 | timeout: 5000 26 | -------------------------------------------------------------------------------- /lib/active_admin/globalize/active_record_extension.rb: -------------------------------------------------------------------------------- 1 | module ActiveAdmin::Globalize 2 | module ActiveRecordExtension 3 | 4 | module Methods 5 | def translation_names 6 | self.translations.map(&:locale).map do |locale| 7 | I18n.t("active_admin.globalize.language.#{locale}") 8 | end.uniq.sort 9 | end 10 | end 11 | 12 | def active_admin_translates(*args, &block) 13 | translates(*args.dup) 14 | args.extract_options! 15 | 16 | if block 17 | translation_class.instance_eval &block 18 | end 19 | 20 | accepts_nested_attributes_for :translations, allow_destroy: true 21 | 22 | include Methods 23 | end 24 | 25 | end 26 | end 27 | 28 | -------------------------------------------------------------------------------- /lib/active_admin/globalize/index_table_for_extension.rb: -------------------------------------------------------------------------------- 1 | require 'active_admin/views/components/status_tag' 2 | 3 | module ActiveAdmin 4 | module Globalize 5 | module IndexTableFor 6 | def translation_status 7 | column I18n.t("active_admin.globalize.translations") do |obj| 8 | obj.translation_names.map do |t| 9 | '%s' % t 10 | end.join(" ").html_safe 11 | end 12 | end 13 | def translation_status_flags 14 | column I18n.t("active_admin.globalize.translations") do |obj| 15 | obj.translations.map(&:locale).sort.map { |l| flag_icon(l) }.join(' ').html_safe 16 | end 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // the compiled file. 9 | // 10 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD 11 | // GO AFTER THE REQUIRES BELOW. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require_tree . 16 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure your secret_key_base is kept private 11 | # if you're sharing your code publicly. 12 | Dummy::Application.config.secret_key_base = 'ac66be52f9b14acad0c94e4f15b35429cbaa88b8c5256eb2bcd74fe0d4e4a15f42d7d7fd97b4de48c510830ced92f23db28a6b636496270d605c87da726e5144' 13 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /spec/dummy/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /lib/active_admin/globalize.rb: -------------------------------------------------------------------------------- 1 | require 'globalize' 2 | require 'activeadmin' 3 | 4 | require 'active_admin/views/index_as_table' 5 | require 'active_admin/globalize/engine' 6 | require 'active_admin/globalize/form_builder_extension' 7 | require 'active_admin/globalize/active_record_extension' 8 | require 'active_admin/globalize/index_table_for_extension' 9 | require 'active_admin/globalize/attributes_table_extension' 10 | require 'active_admin/view_helpers/flag_helper' 11 | 12 | ActiveRecord::Base.send :extend, ActiveAdmin::Globalize::ActiveRecordExtension 13 | 14 | ActiveAdmin::FormBuilder.send :include, ActiveAdmin::Globalize::FormBuilderExtension 15 | ActiveAdmin::Views::IndexAsTable::IndexTableFor.send :include, ActiveAdmin::Globalize::IndexTableFor 16 | 17 | -------------------------------------------------------------------------------- /spec/dummy/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

We're sorry, but something went wrong.

23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /spec/dummy/app/admin/articles.rb: -------------------------------------------------------------------------------- 1 | ActiveAdmin.register Article do 2 | 3 | # Allow translations parameters 4 | permit_params translations_attributes: [:id, :locale, :title, :body, :_destroy] 5 | 6 | index do 7 | id_column 8 | column :title 9 | translation_status 10 | translation_status_flags 11 | actions 12 | end 13 | 14 | show do 15 | attributes_table do 16 | translated_row(:title) 17 | translated_row(:italian_title, locale: :it, field: :title) 18 | translated_row(:body, inline: false) 19 | end 20 | end 21 | 22 | form do |f| 23 | 24 | f.inputs 'Article details' do 25 | f.translated_inputs do |t| 26 | t.input :title 27 | t.input :body 28 | end 29 | end 30 | 31 | f.actions 32 | end 33 | 34 | end 35 | -------------------------------------------------------------------------------- /gemfiles/rails4_2.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "sass-rails" 6 | gem "coffee-rails" 7 | gem "therubyracer", platforms: :ruby 8 | gem "uglifier" 9 | gem "jquery-rails" 10 | gem "devise", "~> 3.2" 11 | gem "rails", "~> 4.2.9" 12 | gem "globalize", "~> 5.0.0" 13 | 14 | group :test do 15 | gem "sqlite3", "~> 1.3.5" 16 | gem "rspec-rails", "~> 3.6.1" 17 | gem "factory_girl_rails", "~> 4.2.1" 18 | gem "database_cleaner", "~> 1.0.1" 19 | gem "spring", require: false 20 | gem "spring-commands-rspec", require: false 21 | gem "capybara", "~> 2.15" 22 | gem "capybara-screenshot" 23 | gem "poltergeist" 24 | gem "fuubar", "~> 2.2" 25 | gem "appraisal" 26 | gem "awesome_print" 27 | gem "pry" 28 | end 29 | 30 | gemspec path: "../" 31 | -------------------------------------------------------------------------------- /gemfiles/rails5_0.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "sass-rails" 6 | gem "coffee-rails" 7 | gem "therubyracer", platforms: :ruby 8 | gem "uglifier" 9 | gem "jquery-rails" 10 | gem "devise", "~> 3.2" 11 | gem "rails", "~> 4.2.9" 12 | gem "globalize", "~> 5.0.0" 13 | 14 | group :test do 15 | gem "sqlite3", "~> 1.3.5" 16 | gem "rspec-rails", "~> 3.6.1" 17 | gem "factory_girl_rails", "~> 4.2.1" 18 | gem "database_cleaner", "~> 1.0.1" 19 | gem "spring", require: false 20 | gem "spring-commands-rspec", require: false 21 | gem "capybara", "~> 2.15" 22 | gem "capybara-screenshot" 23 | gem "poltergeist" 24 | gem "fuubar", "~> 2.2" 25 | gem "appraisal" 26 | gem "awesome_print" 27 | gem "pry" 28 | end 29 | 30 | gemspec path: "../" 31 | -------------------------------------------------------------------------------- /gemfiles/rails5_1.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "sass-rails" 6 | gem "coffee-rails" 7 | gem "therubyracer", platforms: :ruby 8 | gem "uglifier" 9 | gem "jquery-rails" 10 | gem "devise", "~> 4.3" 11 | gem "rails", "~> 5.1.3" 12 | gem "globalize", "~> 5.1.0.beta2" 13 | 14 | group :test do 15 | gem "sqlite3", "~> 1.3.5" 16 | gem "rspec-rails", "~> 3.6.1" 17 | gem "factory_girl_rails", "~> 4.2.1" 18 | gem "database_cleaner", "~> 1.0.1" 19 | gem "spring", require: false 20 | gem "spring-commands-rspec", require: false 21 | gem "capybara", "~> 2.15" 22 | gem "capybara-screenshot" 23 | gem "poltergeist" 24 | gem "fuubar", "~> 2.2" 25 | gem "appraisal" 26 | gem "awesome_print" 27 | gem "pry" 28 | end 29 | 30 | gemspec path: "../" 31 | -------------------------------------------------------------------------------- /spec/dummy/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The change you wanted was rejected.

23 |

Maybe you tried to change something you didn't have access to.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /spec/dummy/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The page you were looking for doesn't exist.

23 |

You may have mistyped the address or the page may have moved.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /spec/models/article_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | # Model taken from the dummy app 4 | describe Article do 5 | 6 | it 'should be translatable' do 7 | Article.translates?.should be_true 8 | end 9 | 10 | describe 'localized article' do 11 | 12 | let(:article) { create(:localized_article) } 13 | subject { article } 14 | 15 | it { should have(3).translations } 16 | 17 | it 'should have italian translation' do 18 | I18n.with_locale :it do 19 | article.title.should == 'Italian title' 20 | article.body.should == 'Italian Body' 21 | end 22 | end 23 | 24 | it 'should have hungarian translation' do 25 | I18n.with_locale :hu do 26 | article.title.should == 'Article title' 27 | article.body.should == 'Hungarian Body' 28 | end 29 | end 30 | 31 | end 32 | 33 | end 34 | -------------------------------------------------------------------------------- /spec/dummy/app/admin/dashboard.rb: -------------------------------------------------------------------------------- 1 | ActiveAdmin.register_page "Dashboard" do 2 | 3 | menu priority: 1, label: proc{ I18n.t("active_admin.dashboard") } 4 | 5 | content title: proc{ I18n.t("active_admin.dashboard") } do 6 | div class: "blank_slate_container", id: "dashboard_default_message" do 7 | span class: "blank_slate" do 8 | span I18n.t("active_admin.dashboard_welcome.welcome") 9 | small I18n.t("active_admin.dashboard_welcome.call_to_action") 10 | end 11 | end 12 | 13 | # Here is an example of a simple dashboard with columns and panels. 14 | # 15 | # columns do 16 | # column do 17 | # panel "Recent Posts" do 18 | # ul do 19 | # Post.recent(5).map do |post| 20 | # li link_to(post.title, admin_post_path(post)) 21 | # end 22 | # end 23 | # end 24 | # end 25 | 26 | # column do 27 | # panel "Info" do 28 | # para "Welcome to ActiveAdmin." 29 | # end 30 | # end 31 | # end 32 | end # content 33 | end 34 | -------------------------------------------------------------------------------- /app/assets/stylesheets/active_admin/active_admin_globalize_mixins.sass: -------------------------------------------------------------------------------- 1 | @mixin border-top-radius($radius) 2 | -webkit-border-top-right-radius: $radius 3 | border-top-right-radius: $radius 4 | -webkit-border-top-left-radius: $radius 5 | border-top-left-radius: $radius 6 | background-clip: padding-box 7 | 8 | @mixin border-right-radius($radius) 9 | -webkit-border-bottom-right-radius: $radius 10 | border-bottom-right-radius: $radius 11 | -webkit-border-top-right-radius: $radius 12 | border-top-right-radius: $radius 13 | background-clip: padding-box 14 | 15 | @mixin border-bottom-radius($radius) 16 | -webkit-border-bottom-right-radius: $radius 17 | border-bottom-right-radius: $radius 18 | -webkit-border-bottom-left-radius: $radius 19 | border-bottom-left-radius: $radius 20 | background-clip: padding-box 21 | 22 | @mixin border-left-radius($radius) 23 | -webkit-border-bottom-left-radius: $radius 24 | border-bottom-left-radius: $radius 25 | -webkit-border-top-left-radius: $radius 26 | border-top-left-radius: $radius 27 | background-clip: padding-box 28 | -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Andrea Pavoni http://andreapavoni.com 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. 21 | -------------------------------------------------------------------------------- /activeadmin-globalize.gemspec: -------------------------------------------------------------------------------- 1 | $:.push File.expand_path('../lib', __FILE__) 2 | 3 | # Maintain your gem's version: 4 | require 'active_admin/globalize/version' 5 | 6 | # Describe your gem and declare its dependencies: 7 | Gem::Specification.new do |s| 8 | s.name = 'activeadmin-globalize' 9 | s.version = ActiveAdmin::Globalize::VERSION 10 | s.authors = ['Stefano Verna', 'Fabio Napoleoni'] 11 | s.email = ['stefano.verna@gmail.com', 'f.napoleoni@gmail.com'] 12 | s.homepage = 'http://github.com/fabn/activeadmin-globalize' 13 | s.summary = 'Handles globalize translations' 14 | s.description = 'Handles globalize translations in ActiveAdmin 1.0 and Rails 4.x-5.x' 15 | 16 | s.files = Dir['{app,config,db,lib}/**/*'] + %w(MIT-LICENSE README.md) 17 | 18 | s.add_dependency 'activeadmin', '>= 1.0', '< 1.2' 19 | # Try to support rails from 3.2 up to 4.2.x 20 | s.add_dependency 'globalize', '>= 3.1.0', '< 6.0' 21 | 22 | # development dependencies 23 | s.add_development_dependency 'bundler', '>= 1.6.1' 24 | s.add_development_dependency 'rake' 25 | # Other development dependencies moved into Gemfile 26 | 27 | end 28 | -------------------------------------------------------------------------------- /spec/dummy/config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'rails/all' 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | require 'active_admin/globalize' 9 | 10 | module Dummy 11 | class Application < Rails::Application 12 | # Settings in config/environments/* take precedence over those specified here. 13 | # Application configuration should go into files in config/initializers 14 | # -- all .rb files in that directory are automatically loaded. 15 | 16 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 17 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 18 | # config.time_zone = 'Central Time (US & Canada)' 19 | 20 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 21 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 22 | config.i18n.default_locale = :en 23 | config.i18n.available_locales = [:de, :en, :hu, :it, :'pt-BR', :'pt-PT'] 24 | 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /spec/dummy/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports and disable caching. 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send. 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger. 20 | config.active_support.deprecation = :log 21 | 22 | # Raise an error on page load if there are pending migrations 23 | config.active_record.migration_error = :page_load 24 | 25 | # Debug mode disables concatenation and preprocessing of assets. 26 | # This option may cause significant delays in view rendering with a large 27 | # number of complex assets. 28 | config.assets.debug = true 29 | end 30 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Declare your gem's dependencies in activeadmin-globalize.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 | 16 | # Gems used by the dummy application 17 | gem 'sass-rails' 18 | gem 'coffee-rails' 19 | 20 | # See https://github.com/sstephenson/execjs#readme for more supported runtimes 21 | gem 'therubyracer', platforms: :ruby 22 | gem 'uglifier' 23 | 24 | # jquery-rails is 25 | gem 'jquery-rails' 26 | 27 | # ActiveAdmin requires devise < 4.0 28 | gem 'devise', '~> 3.2' 29 | 30 | group :test do 31 | gem 'sqlite3', '~> 1.3.5' 32 | gem 'rspec-rails', '~> 3.6.1' 33 | gem 'factory_girl_rails', '~> 4.2.1' 34 | gem 'database_cleaner', '~> 1.0.1' 35 | gem 'spring', require: false 36 | gem 'spring-commands-rspec', require: false 37 | gem 'capybara', '~> 2.15' 38 | gem 'capybara-screenshot' 39 | gem 'poltergeist' 40 | gem 'fuubar', '~> 2.2' 41 | gem 'appraisal' 42 | # Useful to debug tests 43 | gem 'awesome_print' 44 | gem 'pry' 45 | end 46 | -------------------------------------------------------------------------------- /spec/dummy/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure static asset server for tests with Cache-Control for performance. 16 | config.serve_static_assets = true 17 | config.static_cache_control = "public, max-age=3600" 18 | 19 | # Show full error reports and disable caching. 20 | config.consider_all_requests_local = true 21 | config.action_controller.perform_caching = false 22 | 23 | # Raise exceptions instead of rendering exception templates. 24 | config.action_dispatch.show_exceptions = false 25 | 26 | # Disable request forgery protection in test environment. 27 | config.action_controller.allow_forgery_protection = false 28 | 29 | # Tell Action Mailer not to deliver emails to the real world. 30 | # The :test delivery method accumulates sent emails in the 31 | # ActionMailer::Base.deliveries array. 32 | config.action_mailer.delivery_method = :test 33 | 34 | # Print deprecation notices to the stderr. 35 | config.active_support.deprecation = :stderr 36 | end 37 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140611144346_devise_create_admin_users.rb: -------------------------------------------------------------------------------- 1 | class DeviseCreateAdminUsers < ActiveRecord::Migration 2 | def migrate(direction) 3 | super 4 | # Create a default user 5 | AdminUser.create!(:email => 'admin@example.com', :password => 'password', :password_confirmation => 'password') if direction == :up 6 | end 7 | 8 | def change 9 | create_table(:admin_users) do |t| 10 | ## Database authenticatable 11 | t.string :email, null: false, default: "" 12 | t.string :encrypted_password, null: false, default: "" 13 | 14 | ## Recoverable 15 | t.string :reset_password_token 16 | t.datetime :reset_password_sent_at 17 | 18 | ## Rememberable 19 | t.datetime :remember_created_at 20 | 21 | ## Trackable 22 | t.integer :sign_in_count, default: 0, null: false 23 | t.datetime :current_sign_in_at 24 | t.datetime :last_sign_in_at 25 | t.string :current_sign_in_ip 26 | t.string :last_sign_in_ip 27 | 28 | ## Confirmable 29 | # t.string :confirmation_token 30 | # t.datetime :confirmed_at 31 | # t.datetime :confirmation_sent_at 32 | # t.string :unconfirmed_email # Only if using reconfirmable 33 | 34 | ## Lockable 35 | # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts 36 | # t.string :unlock_token # Only if unlock strategy is :email or :both 37 | # t.datetime :locked_at 38 | 39 | 40 | t.timestamps 41 | end 42 | 43 | add_index :admin_users, :email, unique: true 44 | add_index :admin_users, :reset_password_token, unique: true 45 | # add_index :admin_users, :confirmation_token, unique: true 46 | # add_index :admin_users, :unlock_token, unique: true 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is copied to spec/ when you run 'rails generate rspec:install' 2 | ENV['RAILS_ENV'] ||= 'test' 3 | require File.expand_path('../dummy/config/environment', __FILE__) 4 | require 'rspec/rails' 5 | require 'rspec/autorun' 6 | 7 | # Needed in rails4 to run specs, see https://github.com/activeadmin/activeadmin/issues/2712#issuecomment-46798603 8 | require_relative 'dummy/app/admin/articles' 9 | require_relative 'dummy/app/admin/admin_users' 10 | require_relative 'dummy/app/admin/dashboard' 11 | require_relative 'dummy/config/routes' 12 | 13 | # Requires supporting ruby files with custom matchers and macros, etc, 14 | # in spec/support/ and its subdirectories. 15 | Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } 16 | 17 | # `brew install phantomjs` to make it working 18 | require 'capybara/poltergeist' 19 | Capybara.javascript_driver = :poltergeist 20 | # save screenshots and html of failed js tests 21 | require 'capybara-screenshot/rspec' 22 | 23 | RSpec.configure do |config| 24 | config.treat_symbols_as_metadata_keys_with_true_values = true 25 | config.infer_base_class_for_anonymous_controllers = false 26 | config.order = 'random' 27 | 28 | # factory girl shortcuts 29 | config.include FactoryGirl::Syntax::Methods 30 | # Features helpers 31 | config.include Capybara::ActiveAdminHelpers, type: :feature 32 | 33 | config.before(:suite) do 34 | # Ensure database is empty before running specs 35 | DatabaseCleaner.clean_with :truncation 36 | end 37 | 38 | config.before(:each) do 39 | # Switch to truncation if example uses transactions 40 | DatabaseCleaner.strategy = Capybara.current_driver == :rack_test ? :transaction : :truncation 41 | DatabaseCleaner.start 42 | end 43 | 44 | config.after(:each) do 45 | DatabaseCleaner.clean 46 | end 47 | 48 | end 49 | -------------------------------------------------------------------------------- /app/assets/stylesheets/active_admin/active_admin_globalize_flags.sass: -------------------------------------------------------------------------------- 1 | // This file (and the sprite image) is kindly generated by http://flag-sprites.com/ 2 | // and converted to SASS using this converter http://css2sass.heroku.com/ 3 | 4 | // Override flag positions in your stylesheet if you want to change default flags 5 | .flag 6 | display: inline-block 7 | width: 16px 8 | height: 11px 9 | vertical-align: middle 10 | background: image-url('active_admin/flags.png') no-repeat 11 | &.flag-ar // originally flag-ae 12 | background-position: -16px 0 13 | &.flag-br 14 | background-position: -32px 0 15 | &.flag-pt-BR 16 | background-position: -32px 0 17 | &.flag-de 18 | background-position: -48px 0 19 | &.flag-es 20 | background-position: 0 -11px 21 | &.flag-fr 22 | background-position: -16px -11px 23 | &.flag-gb 24 | background-position: -32px -11px 25 | &.flag-hu 26 | background-position: -48px -11px 27 | &.flag-it 28 | background-position: 0 -22px 29 | &.flag-pt 30 | background-position: -16px -22px 31 | &.flag-pt-PT 32 | background-position: -16px -22px 33 | &.flag-tr 34 | background-position: -32px -22px 35 | &.flag-en // originally flag-us 36 | background-position: -48px -22px 37 | &.flag-he // originally flag-il 38 | background-position: 0 -33px 39 | 40 | // Used to distantiate inline locale selector 41 | span.inline-locale-selector 42 | margin-right: 10px 43 | > .ui-translation-trigger 44 | opacity: .4 45 | &.empty 46 | filter: grayscale(100%) 47 | &.active 48 | opacity: 1 49 | 50 | .field-translation.hidden 51 | display: none 52 | 53 | ul.locale-selector 54 | margin-bottom: 0 !important 55 | 56 | div.field-translation 57 | padding: 10px 10px 58 | +inset-shadow(0, -40px, 40px, #ddd) 59 | +border-top-radius(4px) 60 | +border-bottom-radius(6px) 61 | min-height: 80px 62 | 63 | // prevent tr height flickering 64 | span.field-translation.empty 65 | vertical-align: bottom 66 | -------------------------------------------------------------------------------- /lib/active_admin/globalize/form_builder_extension.rb: -------------------------------------------------------------------------------- 1 | module ActiveAdmin 2 | module Globalize 3 | module FormBuilderExtension 4 | extend ActiveSupport::Concern 5 | 6 | def translated_inputs(name = "Translations", options = {}, &block) 7 | options.symbolize_keys! 8 | available_locales = options.fetch(:available_locales, I18n.available_locales) 9 | switch_locale = options.fetch(:switch_locale, false) 10 | default_locale = options.fetch(:default_locale, I18n.default_locale) 11 | template.content_tag(:div, class: "activeadmin-translations") do 12 | template.content_tag(:ul, class: "available-locales") do 13 | available_locales.map do |locale| 14 | default = 'default' if locale == default_locale 15 | template.content_tag(:li) do 16 | I18n.with_locale(switch_locale ? locale : I18n.locale) do 17 | template.content_tag(:a, I18n.t(:"active_admin.globalize.language.#{locale}"), href:".locale-#{locale}", :class => default) 18 | end 19 | end 20 | end.join.html_safe 21 | end << 22 | available_locales.map do |locale| 23 | translation = object.translations.find { |t| t.locale.to_s == locale.to_s } 24 | translation ||= object.translations.build(locale: locale) 25 | fields = proc do |form| 26 | form.input(:locale, as: :hidden) 27 | form.input(:id, as: :hidden) 28 | I18n.with_locale(switch_locale ? locale : I18n.locale) do 29 | block.call(form) 30 | end 31 | end 32 | inputs_for_nested_attributes( 33 | for: [:translations, translation ], 34 | class: "inputs locale locale-#{translation.locale}", 35 | &fields 36 | ) 37 | end.join.html_safe 38 | end 39 | end 40 | 41 | module ClassMethods 42 | end 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /spec/dummy/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended to check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(:version => 20140611153231) do 15 | 16 | create_table "admin_users", :force => true do |t| 17 | t.string "email", :default => "", :null => false 18 | t.string "encrypted_password", :default => "", :null => false 19 | t.string "reset_password_token" 20 | t.datetime "reset_password_sent_at" 21 | t.datetime "remember_created_at" 22 | t.integer "sign_in_count", :default => 0, :null => false 23 | t.datetime "current_sign_in_at" 24 | t.datetime "last_sign_in_at" 25 | t.string "current_sign_in_ip" 26 | t.string "last_sign_in_ip" 27 | t.datetime "created_at", :null => false 28 | t.datetime "updated_at", :null => false 29 | end 30 | 31 | add_index "admin_users", ["email"], :name => "index_admin_users_on_email", :unique => true 32 | add_index "admin_users", ["reset_password_token"], :name => "index_admin_users_on_reset_password_token", :unique => true 33 | 34 | create_table "article_translations", :force => true do |t| 35 | t.integer "article_id" 36 | t.string "locale", :null => false 37 | t.datetime "created_at", :null => false 38 | t.datetime "updated_at", :null => false 39 | t.string "title" 40 | t.text "body" 41 | end 42 | 43 | add_index "article_translations", ["article_id"], :name => "index_article_translations_on_article_id" 44 | add_index "article_translations", ["locale"], :name => "index_article_translations_on_locale" 45 | 46 | create_table "articles", :force => true do |t| 47 | t.string "title" 48 | t.text "body" 49 | t.datetime "created_at", :null => false 50 | t.datetime "updated_at", :null => false 51 | end 52 | 53 | end 54 | -------------------------------------------------------------------------------- /app/assets/stylesheets/active_admin/active_admin_globalize.sass: -------------------------------------------------------------------------------- 1 | @import "active_admin/mixins" 2 | @import "active_admin_globalize_mixins" 3 | @import "active_admin_globalize_flags" 4 | 5 | .active_admin 6 | .activeadmin-translations 7 | margin-bottom: 20px 8 | 9 | &> ul 10 | position: relative 11 | top: 4px 12 | padding: 0 10px 13 | 14 | &> li 15 | display: inline-block 16 | 17 | &> a 18 | display: inline-block 19 | color: #666 20 | margin-right: 3px 21 | text-decoration: none 22 | font-size: 17px 23 | padding: 8px 15px 24 | padding-bottom: 8px + 4px 25 | margin-bottom: 0 26 | position: relative 27 | 28 | &.error 29 | color: #932419 30 | 31 | &.active 32 | background: #f4f4f4 33 | +inset-shadow(0, 4px, 4px, #ddd) 34 | +border-top-radius(4px) 35 | margin-bottom: 0 36 | +gradient($secondary-gradient-stop, #f4f4f4) 37 | text-shadow: 0 1px 0 white 38 | color: #666 !important 39 | 40 | &> span 41 | font-size: 0.75em 42 | font-weight: bold 43 | position: absolute 44 | top: 2px 45 | right: 4px 46 | display: none 47 | 48 | &:hover 49 | +text-shadow(red, 1px, 1px, 2px) 50 | 51 | &:hover 52 | span 53 | display: block 54 | 55 | span.hidden 56 | display: none 57 | 58 | &> li.add-locale 59 | font-weight: bold 60 | position: relative 61 | z-index: 100 62 | 63 | &> ul 64 | display: none 65 | font-size: 17px 66 | font-weight: normal 67 | padding: 0 68 | +border-bottom-radius(4px) 69 | position: absolute 70 | +shadow(3px, 3px, 5px, #aaa) 71 | background: #f4f4f4 72 | z-index: 100 73 | 74 | &> li 75 | font-size: 17px 76 | padding: 8px 15px 77 | padding-bottom: 8px + 4px 78 | margin-bottom: 0 79 | 80 | &:hover 81 | background: #ddd 82 | background: -webkit-linear-gradient(left, $secondary-gradient-stop, #f4f4f4) 83 | background: -moz-linear-gradient(left, $secondary-gradient-stop, #f4f4f4) 84 | background: linear-gradient(left, $secondary-gradient-stop, #f4f4f4) 85 | 86 | &> a 87 | text-decoration: none 88 | color: #666 89 | 90 | &> li:first-child 91 | border-top-right-radius: 4px 92 | 93 | &:hover 94 | background: #f4f4f4 95 | +inset-shadow(0, 4px, 4px, #ddd) 96 | +border-top-radius(4px) 97 | margin-bottom: 0 98 | +gradient($secondary-gradient-stop, #f4f4f4) 99 | text-shadow: 0 1px 0 white 100 | color: #666 !important 101 | 102 | &> ul 103 | display: block 104 | 105 | 106 | &> fieldset.inputs 107 | margin-bottom: 0 108 | 109 | ol 110 | padding-left: 0 111 | width: 100% 112 | 113 | li.hidden 114 | padding: 0 !important 115 | -------------------------------------------------------------------------------- /spec/dummy/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # Code is not reloaded between requests. 5 | config.cache_classes = true 6 | 7 | # Eager load code on boot. This eager loads most of Rails and 8 | # your application in memory, allowing both thread web servers 9 | # and those relying on copy on write to perform better. 10 | # Rake tasks automatically ignore this option for performance. 11 | config.eager_load = true 12 | 13 | # Full error reports are disabled and caching is turned on. 14 | config.consider_all_requests_local = false 15 | config.action_controller.perform_caching = true 16 | 17 | # Enable Rack::Cache to put a simple HTTP cache in front of your application 18 | # Add `rack-cache` to your Gemfile before enabling this. 19 | # For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid. 20 | # config.action_dispatch.rack_cache = true 21 | 22 | # Disable Rails's static asset server (Apache or nginx will already do this). 23 | config.serve_static_assets = false 24 | 25 | # Compress JavaScripts and CSS. 26 | config.assets.js_compressor = :uglifier 27 | # config.assets.css_compressor = :sass 28 | 29 | # Do not fallback to assets pipeline if a precompiled asset is missed. 30 | config.assets.compile = false 31 | 32 | # Generate digests for assets URLs. 33 | config.assets.digest = true 34 | 35 | # Version of your assets, change this if you want to expire all your assets. 36 | config.assets.version = '1.0' 37 | 38 | # Specifies the header that your server uses for sending files. 39 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache 40 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx 41 | 42 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 43 | # config.force_ssl = true 44 | 45 | # Set to :debug to see everything in the log. 46 | config.log_level = :info 47 | 48 | # Prepend all log lines with the following tags. 49 | # config.log_tags = [ :subdomain, :uuid ] 50 | 51 | # Use a different logger for distributed setups. 52 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 53 | 54 | # Use a different cache store in production. 55 | # config.cache_store = :mem_cache_store 56 | 57 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 58 | # config.action_controller.asset_host = "http://assets.example.com" 59 | 60 | # Precompile additional assets. 61 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 62 | # config.assets.precompile += %w( search.js ) 63 | 64 | # Ignore bad email addresses and do not raise email delivery errors. 65 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 66 | # config.action_mailer.raise_delivery_errors = false 67 | 68 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 69 | # the I18n.default_locale when a translation can not be found). 70 | config.i18n.fallbacks = true 71 | 72 | # Send deprecation notices to registered listeners. 73 | config.active_support.deprecation = :notify 74 | 75 | # Disable automatic flushing of the log to improve performance. 76 | # config.autoflush_log = false 77 | 78 | # Use default logging formatter so that PID and timestamp are not suppressed. 79 | config.log_formatter = ::Logger::Formatter.new 80 | end 81 | -------------------------------------------------------------------------------- /spec/support/capybara_activeadmin_helpers.rb: -------------------------------------------------------------------------------- 1 | # @see http://www.elabs.se/blog/51-simple-tricks-to-clean-up-your-capybara-tests 2 | # Helper for layout main elements and utility methods, included in all feature specs 3 | module Capybara 4 | module ActiveAdminHelpers 5 | 6 | # ensure an user is already on a given path 7 | # @param [String] path a path to visit 8 | def ensure_on(path) 9 | visit(path) unless current_path == path 10 | end 11 | 12 | # Ensure user is on dashboard 13 | def visit_dashboard 14 | ensure_on(root_path) 15 | end 16 | 17 | def logout_button 18 | main_menubar.find('#utility_nav a') 19 | end 20 | 21 | # Return model row in the index view for a given instance 22 | def model_row(model) 23 | find("tr##{model.class.model_name.underscore}_#{model.id}") 24 | end 25 | 26 | def main_menubar 27 | find('#header') 28 | end 29 | 30 | # Return AA action bar, i.e. where reside action buttons 31 | def action_bar 32 | find('#titlebar_right') 33 | end 34 | 35 | # Return active admin page body 36 | def page_body 37 | find '#active_admin_content' 38 | end 39 | 40 | # Return a localized subform for editing with globalize 41 | def localized_form(locale = I18n.default_locale) 42 | find "fieldset.inputs.locale.locale-#{locale}" 43 | end 44 | 45 | # Return the container for flash messages 46 | def flash_messages 47 | find('.flashes') 48 | end 49 | 50 | def sidebar 51 | find '#sidebar' 52 | end 53 | 54 | def submit_button 55 | find 'input[type="submit"]' 56 | end 57 | 58 | # Return Nth table row 59 | def table_row_number(n) 60 | find "table tr:nth-child(#{n})" 61 | end 62 | 63 | def first_table_row 64 | table_row_number(1) 65 | end 66 | 67 | def second_table_row 68 | table_row_number(2) 69 | end 70 | 71 | def third_table_row 72 | table_row_number(3) 73 | end 74 | 75 | # Return the anchor element with flag class 76 | def flag_icon(locale = I18n.locale) 77 | find ".flag-#{locale}" 78 | end 79 | 80 | # Return an a element used to trigger language switch using javascript 81 | def flag_link(locale = I18n.locale) 82 | # find the flag icon by class and go back to parent to get the link 83 | find(:xpath, %Q{.//i[contains(@class, "flag-#{locale}")]/..}) 84 | end 85 | 86 | # Link used to switch tabs for translations 87 | def tab_link(locale = I18n.locale) 88 | find %Q{li.translation-tab a[href='.locale-#{locale}']} 89 | end 90 | 91 | # Method used to login a specific user 92 | def login_user(user, password = 'password') 93 | @current_admin_user = user 94 | ensure_on new_admin_user_session_path 95 | fill_login_form(user.email, password) 96 | page.should have_content 'Signed in successfully.' 97 | main_menubar.should have_link(user.email, href: admin_admin_user_path(user)) 98 | end 99 | 100 | # Used to find and submit login form 101 | def fill_login_form(email, password = 'password') 102 | within '#login' do 103 | fill_in 'Email', with: email 104 | fill_in 'Password', with: password 105 | click_button 'Login' 106 | end 107 | end 108 | 109 | # Helper method to get current logged in user, checking its email in the ui 110 | def current_admin_user 111 | @current_admin_user ||= AdminUser.find(find('#current_user a')[:href].split('/').last) 112 | end 113 | end 114 | 115 | end 116 | 117 | -------------------------------------------------------------------------------- /spec/features/article_composing_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | feature 'Article localization features', :js do 4 | 5 | given!(:current_user) { create(:user) } 6 | 7 | before do 8 | login_user(current_user) 9 | end 10 | 11 | scenario 'Create an article' do 12 | 13 | my_title = 'A new article title' 14 | my_body = 'Something interesting to say' 15 | 16 | within(main_menubar) { click_link 'Articles' } 17 | within(action_bar) { click_link 'New Article' } 18 | 19 | within page_body do 20 | # This will fill visible fields i.e. for the default locale 21 | fill_in 'Title', with: my_title 22 | fill_in 'Body', with: my_body 23 | submit_button.click 24 | end 25 | 26 | page.should have_content 'Article was successfully created.' 27 | 28 | # Retrieve created article from database 29 | page.should have_content my_title 30 | page.should have_content my_body 31 | end 32 | 33 | context 'Viewing article translations' do 34 | 35 | given!(:article) { create(:localized_article) } 36 | 37 | before do 38 | # Load article page 39 | ensure_on(admin_article_path(article)) 40 | end 41 | 42 | # See spec/dummy/app/admin/articles.rb 43 | scenario 'Viewing a translated article' do 44 | 45 | # First row shows default locale with label title 46 | within first_table_row do 47 | page.should have_css 'th', text: 'TITLE' 48 | page.should have_css 'span.field-translation', text: article.title 49 | end 50 | # Second row shows italian title by default 51 | within second_table_row do 52 | page.should have_css 'th', text: 'ITALIAN TITLE' 53 | page.should have_css 'span.field-translation', text: article.translation_for(:it).title 54 | end 55 | 56 | end 57 | 58 | scenario 'Switch inline translations' do 59 | 60 | # First row shows default locale with label title 61 | within first_table_row do 62 | page.should have_css 'th', text: 'TITLE' 63 | page.should have_css 'span.field-translation', text: article.title 64 | 65 | flag_link(:hu).find(:xpath, '..').should have_css '.empty:not(.active)' 66 | flag_link(:it).find(:xpath, '..').should have_css ':not(.empty):not(.active)' 67 | 68 | flag_link(:hu).click # change shown translation 69 | flag_link(:hu).find(:xpath, '..').should have_css '.empty.active' 70 | 71 | flag_link(:it).click # change shown translation 72 | flag_link(:it).find(:xpath, '..').should have_css ':not(.empty).active' 73 | 74 | page.should have_css 'span.field-translation', text: article.translation_for(:it).title 75 | end 76 | 77 | end 78 | 79 | scenario 'Switch block translations' do 80 | 81 | # Third table has a block translation element 82 | within third_table_row do 83 | page.should have_css 'th', text: 'BODY' 84 | page.should have_css 'div.field-translation', text: article.body 85 | tab_link(:it).click # change shown translation 86 | page.should have_css 'div.field-translation', text: article.translation_for(:it).body 87 | end 88 | 89 | end 90 | 91 | scenario 'Viewing empty translations' do 92 | # create empty translations for it 93 | I18n.with_locale(:de) { article.update_attributes! title: '', body: '' } 94 | # Reload article page 95 | visit admin_article_path(article) 96 | 97 | # First row shows default locale with label title 98 | within first_table_row do 99 | flag_link(:de).click # change shown translation 100 | page.should have_css 'span.field-translation.empty', text: 'EMPTY' 101 | end 102 | 103 | # Third table has a block translation element 104 | within third_table_row do 105 | tab_link(:de).click # change shown translation 106 | page.should have_css 'div.field-translation span.empty', text: 'EMPTY' 107 | end 108 | 109 | end 110 | 111 | end 112 | 113 | end 114 | -------------------------------------------------------------------------------- /spec/dummy/config/locales/devise.en.yml: -------------------------------------------------------------------------------- 1 | # Additional translations at https://github.com/plataformatec/devise/wiki/I18n 2 | 3 | en: 4 | devise: 5 | confirmations: 6 | confirmed: "Your account was successfully confirmed." 7 | send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." 8 | send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes." 9 | failure: 10 | already_authenticated: "You are already signed in." 11 | inactive: "Your account is not activated yet." 12 | invalid: "Invalid email or password." 13 | locked: "Your account is locked." 14 | last_attempt: "You have one more attempt before your account will be locked." 15 | not_found_in_database: "Invalid email or password." 16 | timeout: "Your session expired. Please sign in again to continue." 17 | unauthenticated: "You need to sign in or sign up before continuing." 18 | unconfirmed: "You have to confirm your account before continuing." 19 | mailer: 20 | confirmation_instructions: 21 | subject: "Confirmation instructions" 22 | reset_password_instructions: 23 | subject: "Reset password instructions" 24 | unlock_instructions: 25 | subject: "Unlock Instructions" 26 | omniauth_callbacks: 27 | failure: "Could not authenticate you from %{kind} because \"%{reason}\"." 28 | success: "Successfully authenticated from %{kind} account." 29 | passwords: 30 | no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided." 31 | send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes." 32 | send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes." 33 | updated: "Your password was changed successfully. You are now signed in." 34 | updated_not_active: "Your password was changed successfully." 35 | registrations: 36 | destroyed: "Bye! Your account was successfully cancelled. We hope to see you again soon." 37 | signed_up: "Welcome! You have signed up successfully." 38 | signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated." 39 | signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked." 40 | signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please open the link to activate your account." 41 | update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and click on the confirm link to finalize confirming your new email address." 42 | updated: "You updated your account successfully." 43 | sessions: 44 | signed_in: "Signed in successfully." 45 | signed_out: "Signed out successfully." 46 | unlocks: 47 | send_instructions: "You will receive an email with instructions about how to unlock your account in a few minutes." 48 | send_paranoid_instructions: "If your account exists, you will receive an email with instructions about how to unlock it in a few minutes." 49 | unlocked: "Your account has been unlocked successfully. Please sign in to continue." 50 | errors: 51 | messages: 52 | already_confirmed: "was already confirmed, please try signing in" 53 | confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one" 54 | expired: "has expired, please request a new one" 55 | not_found: "not found" 56 | not_locked: "was not locked" 57 | not_saved: 58 | one: "1 error prohibited this %{resource} from being saved:" 59 | other: "%{count} errors prohibited this %{resource} from being saved:" 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ActiveAdmin::Globalize 2 | 3 | Makes it easy to translate your resource fields. 4 | 5 | [![Gem Version](https://badge.fury.io/rb/activeadmin-globalize.svg)](http://badge.fury.io/rb/activeadmin-globalize) 6 | [![Build Status](https://travis-ci.org/fabn/activeadmin-globalize.svg?branch=develop)](https://travis-ci.org/fabn/activeadmin-globalize) 7 | 8 | ## Help Needed 9 | 10 | Looking for maintainers. See https://github.com/fabn/activeadmin-globalize/issues/26 11 | 12 | ## Installation 13 | 14 | Current released version on rubygems is `1.0.0.pre`, I won't call it 1.0.0 until some issues has been solved, 15 | but, as reported in [this PR](https://github.com/fabn/activeadmin-globalize/pull/25) it should work with both 16 | AA 1.0.0 and AA 1.1.0. 17 | 18 | Current version targets Rails 4 and greater and ActiveAdmin >= 1.0.0. 19 | 20 | ```ruby 21 | gem 'activeadmin-globalize', '~> 1.0.0.pre' 22 | ``` 23 | 24 | Previous version with support for Rails 3 is maintained in branch [support/0.6.x](https://github.com/fabn/activeadmin-globalize/tree/support/0.6.x) 25 | 26 | ## Require Assets 27 | 28 | - active_admin.js: `//= require active_admin/active_admin_globalize.js` 29 | - active_admin.css: `*= require active_admin/active_admin_globalize` 30 | 31 | ## Your model 32 | 33 | ```ruby 34 | active_admin_translates :title, :description do 35 | validates_presence_of :title 36 | end 37 | ``` 38 | ## In your Active Admin resource definition 39 | 40 | **Important note:** I'm working on a fix for #4 because after AA deprecated and then removed [#form_buffers](https://github.com/activeadmin/activeadmin/pull/3486) the 41 | syntax shown below for form declaration doesn't work as is. See comments in code and [discussion](#4) to fix it until I found a solution. 42 | 43 | ```ruby 44 | 45 | # For usage with strong parameters you'll need to permit them 46 | permit_params translations_attributes: [:id, :locale, :title, :description, :_destroy] 47 | 48 | index do 49 | # textual translation status 50 | translation_status 51 | # or with flag icons 52 | translation_status_flags 53 | # ... 54 | actions 55 | end 56 | 57 | # This was the original syntax proposed in this gem, however currently it doesn't work 58 | form do |f| 59 | # ... 60 | f.translated_inputs "Translated fields", switch_locale: false do |t| 61 | t.input :title 62 | t.input :description 63 | end 64 | # ... 65 | end 66 | 67 | # Instead you have to nest the block inside an #inputs block and the title 68 | # should be passed to the inputs method 69 | form do |f| 70 | # ... 71 | f.inputs "Translated fields" do 72 | f.translated_inputs 'ignored title', switch_locale: false do |t| 73 | t.input :title 74 | t.input :description 75 | end 76 | end 77 | # ... 78 | end 79 | 80 | # You can also set locales to show in tabs 81 | # For example we want to show English translation fields without tab, and want to show other languages within tabs 82 | form do |f| 83 | # ... 84 | f.inputs do 85 | Globalize.with_locale(:en) do 86 | f.input :title 87 | end 88 | end 89 | f.inputs "Translated fields" do 90 | f.translated_inputs 'ignored title', switch_locale: false, available_locales: (I18n.available_locales - [:en]) do |t| 91 | t.input :title 92 | t.input :description 93 | end 94 | end 95 | # ... 96 | end 97 | 98 | # You can also set default language tab 99 | # For example we want to make Bengali translation tab as default 100 | form do |f| 101 | # ... 102 | f.inputs "Translated fields" do 103 | f.translated_inputs 'ignored title', switch_locale: false, default_locale: :bn do |t| 104 | t.input :title 105 | t.input :description 106 | end 107 | end 108 | # ... 109 | end 110 | 111 | ``` 112 | If `switch_locale` is set, each tab will be rendered switching locale. 113 | 114 | 115 | ## Hints 116 | 117 | To use the dashed locale keys as 'pt-BR' or 'pt-PT' you need to convert a string 118 | to symbol (in application.rb) 119 | 120 | ```ruby 121 | config.i18n.available_locales = [:en, :it, :de, :es, :"pt-BR"] 122 | ``` 123 | 124 | ## Credits 125 | 126 | This work is based on original idea by [@stefanoverna](https://github.com/stefanoverna/activeadmin-globalize), 127 | I needed it for AA 0.6.x so I forked the original project and expanded it with more features. 128 | -------------------------------------------------------------------------------- /app/assets/javascripts/active_admin/active_admin_globalize.js.coffee: -------------------------------------------------------------------------------- 1 | $ -> 2 | 3 | translations = -> 4 | 5 | # Hides or shows the + button and the remove button. 6 | updateLocaleButtonsStatus = ($dom) -> 7 | $localeList = $dom.find('.add-locale ul li:not(.hidden)') 8 | if $localeList.length == 0 9 | $dom.find('.add-locale').hide() 10 | else 11 | $dom.find('.add-locale').show() 12 | 13 | 14 | # Hides or shows the locale tab and its corresponding element in the add menu. 15 | toggleTab = ($tab, active) -> 16 | $addButton = $tab.parents('ul').find('.add-locale li:has(a[href="' + $tab.attr('href') + '"])') 17 | if active 18 | $tab.addClass('hidden').show().removeClass('hidden') 19 | $addButton.hide().addClass('hidden') 20 | else 21 | $tab.addClass('hidden').hide().addClass('hidden') 22 | $addButton.show().removeClass('hidden') 23 | 24 | $(".activeadmin-translations > ul").each -> 25 | $dom = $(this) 26 | # true when tabs are used in show action, false in form 27 | showAction = $dom.hasClass('locale-selector') 28 | 29 | if !$dom.data("ready") 30 | $dom.data("ready", true) 31 | $tabs = $("li > a", this) 32 | # content to toggle is different according to current action 33 | $contents = if showAction then $(this).siblings("div.field-translation") else $(this).siblings("fieldset") 34 | 35 | $tabs.click (e) -> 36 | $tab = $(this) 37 | $tabs.not($tab).removeClass("active") 38 | $tab.addClass("active") 39 | $contents.hide() 40 | $contents.filter($tab.attr("href")).show() 41 | e.preventDefault() 42 | 43 | $tabs.eq(0).click() 44 | 45 | # Add button and other behavior is not needed in show action 46 | return if showAction 47 | 48 | # Collect tha available locales. 49 | availableLocales = [] 50 | $tabs.not('.default').each -> 51 | availableLocales.push($('
  • ').append($(this).clone().removeClass('active'))) 52 | 53 | # Create a new tab as the root of the drop down menu. 54 | $addLocaleButton = $('
  • +
  • ') 55 | $addLocaleButton.append($('').append(availableLocales)) 56 | 57 | # Handle locale addition 58 | $addLocaleButton.find('ul a').click (e) -> 59 | href = $(this).attr('href') 60 | $tab = $tabs.filter('[href="' + href + '"]') 61 | toggleTab($tab, true) 62 | $tab.click() 63 | updateLocaleButtonsStatus($dom) 64 | e.preventDefault() 65 | 66 | # Remove a locale from the tab. 67 | $removeButton = $('x').click (e) -> 68 | e.stopImmediatePropagation() 69 | e.preventDefault() 70 | $tab = $(this).parent() 71 | toggleTab($tab, false) 72 | if $tab.hasClass('active') 73 | $tabs.not('.hidden').eq(0).click() 74 | 75 | updateLocaleButtonsStatus($dom) 76 | 77 | # Add the remove button to every tab. 78 | $tabs.not('.default').append($removeButton) 79 | 80 | # Add the new button at the end of the locale list. 81 | $dom.append($addLocaleButton) 82 | 83 | $tabs.each -> 84 | $tab = $(@) 85 | $content = $contents.filter($tab.attr("href")) 86 | containsErrors = $content.find(".input.error").length > 0 87 | $tab.toggleClass("error", containsErrors) 88 | # Find those tabs that are in use. 89 | hide = true 90 | # We will not hide the tabs that have any error. 91 | if $tab.hasClass('error') || $tab.hasClass('default') 92 | hide = false 93 | else 94 | # Check whether the input fields are empty or not. 95 | $content.find('[name]').not('[type="hidden"]').each -> 96 | if $(this).val() 97 | # We will not hide the tab because it has some data. 98 | hide = false 99 | return false 100 | 101 | if hide 102 | toggleTab($tab, false) 103 | else 104 | toggleTab($tab, true) 105 | 106 | # Remove the fields of hidden locales before form submission. 107 | $form = $dom.parents('form') 108 | if !$form.data('ready') 109 | $form.data('ready') 110 | $form.submit -> 111 | # Get all translations (the nested ones too). 112 | $('.activeadmin-translations > ul').each -> 113 | # Get the corresponding fieldsets. 114 | $fieldsets = $(this).siblings('fieldset') 115 | $("li:not(.add-locale) > a", this).each -> 116 | # Remove them if the locale is hidden. 117 | if $(this).hasClass('hidden') 118 | # check if it's an existing translation otherwise remove it 119 | $currentFieldset = $("fieldset#{$(this).attr('href')}") 120 | $translationId = $('input[id$=_id]', $currentFieldset) 121 | if $translationId.val() 122 | # mark it for database removal appending a _destroy element 123 | $destroy = $('').attr( 124 | type: 'hidden', 125 | name: $translationId.attr('name').replace('[id]', '[_destroy]'), 126 | id: $translationId.attr('id').replace('_id', '_destroy'), 127 | value: '1' 128 | ) 129 | $destroy.appendTo($currentFieldset) 130 | else 131 | # remove the fieldset from dom so it won't be submitted 132 | $fieldsets.filter($(this).attr('href')).remove() 133 | 134 | #Initially update the buttons' status 135 | updateLocaleButtonsStatus($dom) 136 | $tabs.filter('.default').click() 137 | 138 | # this is to handle elements created with has_many 139 | $("a").bind "click", -> 140 | setTimeout( 141 | -> translations() 142 | 50 143 | ) 144 | 145 | # Used to toggle translations values for inline fields 146 | $('a.ui-translation-trigger').click (e) -> 147 | $locale = $(this).data('locale') 148 | $td = $(this).closest('td') 149 | $('.field-translation', $td).hide() 150 | $(".locale-#{$locale}", $td).show() 151 | $(this).parent().children('a.ui-translation-trigger').removeClass('active') 152 | $(this).addClass('active') 153 | e.preventDefault() 154 | 155 | translations() 156 | -------------------------------------------------------------------------------- /lib/active_admin/globalize/attributes_table_extension.rb: -------------------------------------------------------------------------------- 1 | require 'active_admin/views/components/attributes_table.rb' 2 | 3 | module ActiveAdmin 4 | module Views 5 | 6 | # Provide additional method #translated_row to attribute table 7 | class AttributesTable < ActiveAdmin::Component 8 | 9 | # Show a row with their translations and selectors for choosing locale to show. 10 | # 11 | # If a block is given it will be used to format the translation, 12 | # otherwise field taken from translation object is used as translation. 13 | # 14 | # Additional options are forwarded to the original row call. 15 | # 16 | # @overload translated_row(field, opts) 17 | # @param [String] field row label, also used as field name if none given in options 18 | # @param [Hash] opts the options to create a message with. 19 | # @option opts [String] :field field to retrieve from model if different from first argument of args 20 | # @option opts [String] :locale (I18n.locale) initial locale to show in the ui 21 | # @option opts [Boolean] :inline (true) if true locale selectors (and values) are shown inline, 22 | # otherwise as block content and tabs 23 | # 24 | # @yield if given will be used to build single translations 25 | # @yieldparam [*::Translation] Globalize translation model 26 | # @yieldreturn [String] content to show as translation 27 | # 28 | # @example Show inlined translation values for title field 29 | # show do |p| 30 | # attributes_table do 31 | # translated_row(:title) 32 | # end 33 | # end 34 | # 35 | # @example Show block translation for body field with selection of initial locale 36 | # show do |p| 37 | # attributes_table do 38 | # translated_row(:body, inline: false, locale: :es) 39 | # end 40 | # end 41 | # 42 | def translated_row(*args, &block) 43 | options = args.extract_options! 44 | options.reverse_merge!(inline: true, locale: I18n.locale) 45 | field = options[:field] || args.first 46 | raise ArgumentError, "Field '#{field}' is not translatable" unless translatable?(field) 47 | # Remove my options from passed options 48 | row_options = options.symbolize_keys.except(:field, :locale, :inline) 49 | # Append remaining options to original args 50 | args.push(row_options) unless row_options.empty? 51 | # Render the table row with translations 52 | row(*args) do 53 | if options[:inline] 54 | ''.html_safe.tap do |value| 55 | # Add selectors for inline locale 56 | value << inline_locale_selectors(field, options[:locale], &block) 57 | # Build translations spans 58 | value << field_translations(field, :span, options[:locale], &block) 59 | end 60 | else 61 | content_tag(:div, class: 'activeadmin-translations') do 62 | ''.html_safe.tap do |value| 63 | # Render selectors as in translation ui 64 | value << block_locale_selectors(field, options[:locale], &block) 65 | # Build translations divs for actual translations 66 | value << field_translations(field, :div, options[:locale], &block) 67 | end 68 | end 69 | end 70 | end 71 | end 72 | 73 | private 74 | 75 | # @return [Boolean] true iff the field is translatable 76 | def translatable?(field) 77 | @resource_class.translates? && 78 | @resource_class.translated_attribute_names.include?(field.to_sym) 79 | end 80 | 81 | # Build a tag for each field translation with appropriate css classes to make javascript working 82 | # @param [String] field field name to render 83 | # @param [Symbol] tag tag to enclose field translation 84 | # @param [Symbol] initial_locale locale to set as not hidden 85 | def field_translations(field, tag, initial_locale, &block) 86 | available_translations.map do |translation| 87 | # Classes for translation span only first element is visible 88 | css_classes = ['field-translation', "locale-#{translation.locale}"] 89 | # Initially only element for selected locale is visible 90 | css_classes.push 'hidden' unless translation.locale == initial_locale.to_sym 91 | # Build content for cell or div using translation locale and given block 92 | content = field_translation_value(translation, field, &block) 93 | # return element 94 | if tag == :span # inline element 95 | # attach class to span if inline 96 | css_classes.push('empty') if content.blank? 97 | content_tag(tag, content.presence || 'Empty', class: css_classes) 98 | else 99 | # block content 100 | content_tag(tag, class: css_classes) do 101 | # Return content or empty span 102 | content.presence || content_tag(:span, 'Empty', class: 'empty') 103 | end 104 | end 105 | end.join(' ').html_safe 106 | end 107 | 108 | def block_locale_selectors(field, initial_locale, &block) 109 | content_tag(:ul, class: 'available-locales locale-selector') do 110 | available_translations.map do |translation| 111 | css_classes = ['translation-tab'] 112 | css_classes << 'active' if translation.locale == initial_locale.to_sym 113 | css_classes << 'empty' unless content.presence 114 | content_tag(:li, class: css_classes) do 115 | I18n.with_locale(translation.locale) do 116 | default = 'default' if translation.locale == initial_locale.to_sym 117 | content_tag(:a, I18n.t(:"active_admin.globalize.language.#{translation.locale}"), href: ".locale-#{translation.locale}", class: default) 118 | end 119 | end 120 | end.join.html_safe 121 | end 122 | end 123 | 124 | # Return flag elements to show the given locale using javascript 125 | def inline_locale_selectors(field, initial_locale, &block) 126 | content_tag(:span, class: 'inline-locale-selector') do 127 | available_translations.map do |translation| 128 | content = field_translation_value(translation, field, &block) 129 | css_classes = ['ui-translation-trigger'] 130 | css_classes << 'active' if translation.locale == initial_locale.to_sym 131 | css_classes << 'empty' unless content.presence 132 | # Build a link to show the given translation 133 | link_to(flag_icon(translation.locale), '#', class: css_classes, data: {locale: translation.locale}) 134 | end.join(' ').html_safe 135 | end 136 | end 137 | 138 | def available_translations 139 | @record_translations ||= @collection.first.translations.order(:locale) 140 | end 141 | 142 | def field_translation_value(translation, field) 143 | I18n.with_locale(translation.locale) do 144 | block_given? ? yield(translation) : translation.send(field) 145 | end 146 | end 147 | end 148 | end 149 | end 150 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/active_admin.rb: -------------------------------------------------------------------------------- 1 | ActiveAdmin.setup do |config| 2 | 3 | # == Site Title 4 | # 5 | # Set the title that is displayed on the main layout 6 | # for each of the active admin pages. 7 | # 8 | config.site_title = "Dummy" 9 | 10 | # Set the link url for the title. For example, to take 11 | # users to your main site. Defaults to no link. 12 | # 13 | # config.site_title_link = "/" 14 | 15 | # Set an optional image to be displayed for the header 16 | # instead of a string (overrides :site_title) 17 | # 18 | # Note: Aim for an image that's 21px high so it fits in the header. 19 | # 20 | # config.site_title_image = "logo.png" 21 | 22 | # == Default Namespace 23 | # 24 | # Set the default namespace each administration resource 25 | # will be added to. 26 | # 27 | # eg: 28 | # config.default_namespace = :hello_world 29 | # 30 | # This will create resources in the HelloWorld module and 31 | # will namespace routes to /hello_world/* 32 | # 33 | # To set no namespace by default, use: 34 | # config.default_namespace = false 35 | # 36 | # Default: 37 | # config.default_namespace = :admin 38 | # 39 | # You can customize the settings for each namespace by using 40 | # a namespace block. For example, to change the site title 41 | # within a namespace: 42 | # 43 | # config.namespace :admin do |admin| 44 | # admin.site_title = "Custom Admin Title" 45 | # end 46 | # 47 | # This will ONLY change the title for the admin section. Other 48 | # namespaces will continue to use the main "site_title" configuration. 49 | 50 | # == User Authentication 51 | # 52 | # Active Admin will automatically call an authentication 53 | # method in a before filter of all controller actions to 54 | # ensure that there is a currently logged in admin user. 55 | # 56 | # This setting changes the method which Active Admin calls 57 | # within the application controller. 58 | config.authentication_method = :authenticate_admin_user! 59 | 60 | # == User Authorization 61 | # 62 | # Active Admin will automatically call an authorization 63 | # method in a before filter of all controller actions to 64 | # ensure that there is a user with proper rights. You can use 65 | # CanCanAdapter or make your own. Please refer to documentation. 66 | # config.authorization_adapter = ActiveAdmin::CanCanAdapter 67 | 68 | # You can customize your CanCan Ability class name here. 69 | # config.cancan_ability_class = "Ability" 70 | 71 | # You can specify a method to be called on unauthorized access. 72 | # This is necessary in order to prevent a redirect loop which happens 73 | # because, by default, user gets redirected to Dashboard. If user 74 | # doesn't have access to Dashboard, he'll end up in a redirect loop. 75 | # Method provided here should be defined in application_controller.rb. 76 | # config.on_unauthorized_access = :access_denied 77 | 78 | # == Current User 79 | # 80 | # Active Admin will associate actions with the current 81 | # user performing them. 82 | # 83 | # This setting changes the method which Active Admin calls 84 | # (within the application controller) to return the currently logged in user. 85 | config.current_user_method = :current_admin_user 86 | 87 | 88 | # == Logging Out 89 | # 90 | # Active Admin displays a logout link on each screen. These 91 | # settings configure the location and method used for the link. 92 | # 93 | # This setting changes the path where the link points to. If it's 94 | # a string, the strings is used as the path. If it's a Symbol, we 95 | # will call the method to return the path. 96 | # 97 | # Default: 98 | config.logout_link_path = :destroy_admin_user_session_path 99 | 100 | # This setting changes the http method used when rendering the 101 | # link. For example :get, :delete, :put, etc.. 102 | # 103 | # Default: 104 | # config.logout_link_method = :get 105 | 106 | 107 | # == Root 108 | # 109 | # Set the action to call for the root path. You can set different 110 | # roots for each namespace. 111 | # 112 | # Default: 113 | # config.root_to = 'dashboard#index' 114 | 115 | 116 | # == Admin Comments 117 | # 118 | # This allows your users to comment on any resource registered with Active Admin. 119 | # 120 | # You can completely disable comments: 121 | # config.allow_comments = false 122 | # 123 | # You can disable the menu item for the comments index page: 124 | # config.show_comments_in_menu = false 125 | # 126 | # You can change the name under which comments are registered: 127 | # config.comments_registration_name = 'AdminComment' 128 | 129 | 130 | # == Batch Actions 131 | # 132 | # Enable and disable Batch Actions 133 | # 134 | config.batch_actions = true 135 | 136 | 137 | # == Controller Filters 138 | # 139 | # You can add before, after and around filters to all of your 140 | # Active Admin resources and pages from here. 141 | # 142 | # config.before_filter :do_something_awesome 143 | 144 | 145 | # == Setting a Favicon 146 | # 147 | # config.favicon = '/assets/favicon.ico' 148 | 149 | 150 | # == Removing Breadcrumbs 151 | # 152 | # Breadcrumbs are enabled by default. You can customize them for individual 153 | # resources or you can disable them globally from here. 154 | # 155 | # config.breadcrumb = false 156 | 157 | 158 | # == Register Stylesheets & Javascripts 159 | # 160 | # We recommend using the built in Active Admin layout and loading 161 | # up your own stylesheets / javascripts to customize the look 162 | # and feel. 163 | # 164 | # To load a stylesheet: 165 | # config.register_stylesheet 'my_stylesheet.css' 166 | # 167 | # You can provide an options hash for more control, which is passed along to stylesheet_link_tag(): 168 | # config.register_stylesheet 'my_print_stylesheet.css', :media => :print 169 | # 170 | # To load a javascript file: 171 | # config.register_javascript 'my_javascript.js' 172 | 173 | 174 | # == CSV options 175 | # 176 | # Set the CSV builder separator 177 | # config.csv_options = { :col_sep => ';' } 178 | # 179 | # Force the use of quotes 180 | # config.csv_options = { :force_quotes => true } 181 | 182 | 183 | # == Menu System 184 | # 185 | # You can add a navigation menu to be used in your application, or configure a provided menu 186 | # 187 | # To change the default utility navigation to show a link to your website & a logout btn 188 | # 189 | # config.namespace :admin do |admin| 190 | # admin.build_menu :utility_navigation do |menu| 191 | # menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank } 192 | # admin.add_logout_button_to_menu menu 193 | # end 194 | # end 195 | # 196 | # If you wanted to add a static menu item to the default menu provided: 197 | # 198 | # config.namespace :admin do |admin| 199 | # admin.build_menu :default do |menu| 200 | # menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank } 201 | # end 202 | # end 203 | 204 | 205 | # == Download Links 206 | # 207 | # You can disable download links on resource listing pages, 208 | # or customize the formats shown per namespace/globally 209 | # 210 | # To disable/customize for the :admin namespace: 211 | # 212 | # config.namespace :admin do |admin| 213 | # 214 | # # Disable the links entirely 215 | # admin.download_links = false 216 | # 217 | # # Only show XML & PDF options 218 | # admin.download_links = [:xml, :pdf] 219 | # 220 | # # Enable/disable the links based on block 221 | # # (for example, with cancan) 222 | # admin.download_links = proc { can?(:view_download_links) } 223 | # 224 | # end 225 | 226 | 227 | # == Pagination 228 | # 229 | # Pagination is enabled by default for all resources. 230 | # You can control the default per page count for all resources here. 231 | # 232 | # config.default_per_page = 30 233 | 234 | 235 | # == Filters 236 | # 237 | # By default the index screen includes a “Filters” sidebar on the right 238 | # hand side with a filter for each attribute of the registered model. 239 | # You can enable or disable them for all resources here. 240 | # 241 | # config.filters = true 242 | 243 | end 244 | -------------------------------------------------------------------------------- /spec/dummy/README.rdoc: -------------------------------------------------------------------------------- 1 | == Welcome to Rails 2 | 3 | Rails is a web-application framework that includes everything needed to create 4 | database-backed web applications according to the Model-View-Control pattern. 5 | 6 | This pattern splits the view (also called the presentation) into "dumb" 7 | templates that are primarily responsible for inserting pre-built data in between 8 | HTML tags. The model contains the "smart" domain objects (such as Account, 9 | Product, Person, Post) that holds all the business logic and knows how to 10 | persist themselves to a database. The controller handles the incoming requests 11 | (such as Save New Account, Update Product, Show Post) by manipulating the model 12 | and directing data to the view. 13 | 14 | In Rails, the model is handled by what's called an object-relational mapping 15 | layer entitled Active Record. This layer allows you to present the data from 16 | database rows as objects and embellish these data objects with business logic 17 | methods. You can read more about Active Record in 18 | link:files/vendor/rails/activerecord/README.html. 19 | 20 | The controller and view are handled by the Action Pack, which handles both 21 | layers by its two parts: Action View and Action Controller. These two layers 22 | are bundled in a single package due to their heavy interdependence. This is 23 | unlike the relationship between the Active Record and Action Pack that is much 24 | more separate. Each of these packages can be used independently outside of 25 | Rails. You can read more about Action Pack in 26 | link:files/vendor/rails/actionpack/README.html. 27 | 28 | 29 | == Getting Started 30 | 31 | 1. At the command prompt, create a new Rails application: 32 | rails new myapp (where myapp is the application name) 33 | 34 | 2. Change directory to myapp and start the web server: 35 | cd myapp; rails server (run with --help for options) 36 | 37 | 3. Go to http://localhost:3000/ and you'll see: 38 | "Welcome aboard: You're riding Ruby on Rails!" 39 | 40 | 4. Follow the guidelines to start developing your application. You can find 41 | the following resources handy: 42 | 43 | * The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html 44 | * Ruby on Rails Tutorial Book: http://www.railstutorial.org/ 45 | 46 | 47 | == Debugging Rails 48 | 49 | Sometimes your application goes wrong. Fortunately there are a lot of tools that 50 | will help you debug it and get it back on the rails. 51 | 52 | First area to check is the application log files. Have "tail -f" commands 53 | running on the server.log and development.log. Rails will automatically display 54 | debugging and runtime information to these files. Debugging info will also be 55 | shown in the browser on requests from 127.0.0.1. 56 | 57 | You can also log your own messages directly into the log file from your code 58 | using the Ruby logger class from inside your controllers. Example: 59 | 60 | class WeblogController < ActionController::Base 61 | def destroy 62 | @weblog = Weblog.find(params[:id]) 63 | @weblog.destroy 64 | logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!") 65 | end 66 | end 67 | 68 | The result will be a message in your log file along the lines of: 69 | 70 | Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1! 71 | 72 | More information on how to use the logger is at http://www.ruby-doc.org/core/ 73 | 74 | Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are 75 | several books available online as well: 76 | 77 | * Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe) 78 | * Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide) 79 | 80 | These two books will bring you up to speed on the Ruby language and also on 81 | programming in general. 82 | 83 | 84 | == Debugger 85 | 86 | Debugger support is available through the debugger command when you start your 87 | Mongrel or WEBrick server with --debugger. This means that you can break out of 88 | execution at any point in the code, investigate and change the model, and then, 89 | resume execution! You need to install ruby-debug to run the server in debugging 90 | mode. With gems, use sudo gem install ruby-debug. Example: 91 | 92 | class WeblogController < ActionController::Base 93 | def index 94 | @posts = Post.all 95 | debugger 96 | end 97 | end 98 | 99 | So the controller will accept the action, run the first line, then present you 100 | with a IRB prompt in the server window. Here you can do things like: 101 | 102 | >> @posts.inspect 103 | => "[#nil, "body"=>nil, "id"=>"1"}>, 105 | #"Rails", "body"=>"Only ten..", "id"=>"2"}>]" 107 | >> @posts.first.title = "hello from a debugger" 108 | => "hello from a debugger" 109 | 110 | ...and even better, you can examine how your runtime objects actually work: 111 | 112 | >> f = @posts.first 113 | => #nil, "body"=>nil, "id"=>"1"}> 114 | >> f. 115 | Display all 152 possibilities? (y or n) 116 | 117 | Finally, when you're ready to resume execution, you can enter "cont". 118 | 119 | 120 | == Console 121 | 122 | The console is a Ruby shell, which allows you to interact with your 123 | application's domain model. Here you'll have all parts of the application 124 | configured, just like it is when the application is running. You can inspect 125 | domain models, change values, and save to the database. Starting the script 126 | without arguments will launch it in the development environment. 127 | 128 | To start the console, run rails console from the application 129 | directory. 130 | 131 | Options: 132 | 133 | * Passing the -s, --sandbox argument will rollback any modifications 134 | made to the database. 135 | * Passing an environment name as an argument will load the corresponding 136 | environment. Example: rails console production. 137 | 138 | To reload your controllers and models after launching the console run 139 | reload! 140 | 141 | More information about irb can be found at: 142 | link:http://www.rubycentral.org/pickaxe/irb.html 143 | 144 | 145 | == dbconsole 146 | 147 | You can go to the command line of your database directly through rails 148 | dbconsole. You would be connected to the database with the credentials 149 | defined in database.yml. Starting the script without arguments will connect you 150 | to the development database. Passing an argument will connect you to a different 151 | database, like rails dbconsole production. Currently works for MySQL, 152 | PostgreSQL and SQLite 3. 153 | 154 | == Description of Contents 155 | 156 | The default directory structure of a generated Ruby on Rails application: 157 | 158 | |-- app 159 | | |-- assets 160 | | | |-- images 161 | | | |-- javascripts 162 | | | `-- stylesheets 163 | | |-- controllers 164 | | |-- helpers 165 | | |-- mailers 166 | | |-- models 167 | | `-- views 168 | | `-- layouts 169 | |-- config 170 | | |-- environments 171 | | |-- initializers 172 | | `-- locales 173 | |-- db 174 | |-- doc 175 | |-- lib 176 | | |-- assets 177 | | `-- tasks 178 | |-- log 179 | |-- public 180 | |-- script 181 | |-- test 182 | | |-- fixtures 183 | | |-- functional 184 | | |-- integration 185 | | |-- performance 186 | | `-- unit 187 | |-- tmp 188 | | `-- cache 189 | | `-- assets 190 | `-- vendor 191 | |-- assets 192 | | |-- javascripts 193 | | `-- stylesheets 194 | `-- plugins 195 | 196 | app 197 | Holds all the code that's specific to this particular application. 198 | 199 | app/assets 200 | Contains subdirectories for images, stylesheets, and JavaScript files. 201 | 202 | app/controllers 203 | Holds controllers that should be named like weblogs_controller.rb for 204 | automated URL mapping. All controllers should descend from 205 | ApplicationController which itself descends from ActionController::Base. 206 | 207 | app/models 208 | Holds models that should be named like post.rb. Models descend from 209 | ActiveRecord::Base by default. 210 | 211 | app/views 212 | Holds the template files for the view that should be named like 213 | weblogs/index.html.erb for the WeblogsController#index action. All views use 214 | eRuby syntax by default. 215 | 216 | app/views/layouts 217 | Holds the template files for layouts to be used with views. This models the 218 | common header/footer method of wrapping views. In your views, define a layout 219 | using the layout :default and create a file named default.html.erb. 220 | Inside default.html.erb, call <% yield %> to render the view using this 221 | layout. 222 | 223 | app/helpers 224 | Holds view helpers that should be named like weblogs_helper.rb. These are 225 | generated for you automatically when using generators for controllers. 226 | Helpers can be used to wrap functionality for your views into methods. 227 | 228 | config 229 | Configuration files for the Rails environment, the routing map, the database, 230 | and other dependencies. 231 | 232 | db 233 | Contains the database schema in schema.rb. db/migrate contains all the 234 | sequence of Migrations for your schema. 235 | 236 | doc 237 | This directory is where your application documentation will be stored when 238 | generated using rake doc:app 239 | 240 | lib 241 | Application specific libraries. Basically, any kind of custom code that 242 | doesn't belong under controllers, models, or helpers. This directory is in 243 | the load path. 244 | 245 | public 246 | The directory available for the web server. Also contains the dispatchers and the 247 | default HTML files. This should be set as the DOCUMENT_ROOT of your web 248 | server. 249 | 250 | script 251 | Helper scripts for automation and generation. 252 | 253 | test 254 | Unit and functional tests along with fixtures. When using the rails generate 255 | command, template test files will be generated for you and placed in this 256 | directory. 257 | 258 | vendor 259 | External libraries that the application depends on. Also includes the plugins 260 | subdirectory. If the app has frozen rails, those gems also go here, under 261 | vendor/rails/. This directory is in the load path. 262 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/devise.rb: -------------------------------------------------------------------------------- 1 | # Use this hook to configure devise mailer, warden hooks and so forth. 2 | # Many of these configuration options can be set straight in your model. 3 | Devise.setup do |config| 4 | # The secret key used by Devise. Devise uses this key to generate 5 | # random tokens. Changing this key will render invalid all existing 6 | # confirmation, reset password and unlock tokens in the database. 7 | config.secret_key = '00adee3d99b3b7a8fa75b27911a7ce14e677fa4570d04f301791bf40ca901c6370ec96ab95cb4426887bb1f5040888abaa460f59198754fd76ef17863bf9fcb9' 8 | 9 | # ==> Mailer Configuration 10 | # Configure the e-mail address which will be shown in Devise::Mailer, 11 | # note that it will be overwritten if you use your own mailer class 12 | # with default "from" parameter. 13 | config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com' 14 | 15 | # Configure the class responsible to send e-mails. 16 | # config.mailer = 'Devise::Mailer' 17 | 18 | # ==> ORM configuration 19 | # Load and configure the ORM. Supports :active_record (default) and 20 | # :mongoid (bson_ext recommended) by default. Other ORMs may be 21 | # available as additional gems. 22 | require 'devise/orm/active_record' 23 | 24 | # ==> Configuration for any authentication mechanism 25 | # Configure which keys are used when authenticating a user. The default is 26 | # just :email. You can configure it to use [:username, :subdomain], so for 27 | # authenticating a user, both parameters are required. Remember that those 28 | # parameters are used only when authenticating and not when retrieving from 29 | # session. If you need permissions, you should implement that in a before filter. 30 | # You can also supply a hash where the value is a boolean determining whether 31 | # or not authentication should be aborted when the value is not present. 32 | # config.authentication_keys = [ :email ] 33 | 34 | # Configure parameters from the request object used for authentication. Each entry 35 | # given should be a request method and it will automatically be passed to the 36 | # find_for_authentication method and considered in your model lookup. For instance, 37 | # if you set :request_keys to [:subdomain], :subdomain will be used on authentication. 38 | # The same considerations mentioned for authentication_keys also apply to request_keys. 39 | # config.request_keys = [] 40 | 41 | # Configure which authentication keys should be case-insensitive. 42 | # These keys will be downcased upon creating or modifying a user and when used 43 | # to authenticate or find a user. Default is :email. 44 | config.case_insensitive_keys = [ :email ] 45 | 46 | # Configure which authentication keys should have whitespace stripped. 47 | # These keys will have whitespace before and after removed upon creating or 48 | # modifying a user and when used to authenticate or find a user. Default is :email. 49 | config.strip_whitespace_keys = [ :email ] 50 | 51 | # Tell if authentication through request.params is enabled. True by default. 52 | # It can be set to an array that will enable params authentication only for the 53 | # given strategies, for example, `config.params_authenticatable = [:database]` will 54 | # enable it only for database (email + password) authentication. 55 | # config.params_authenticatable = true 56 | 57 | # Tell if authentication through HTTP Auth is enabled. False by default. 58 | # It can be set to an array that will enable http authentication only for the 59 | # given strategies, for example, `config.http_authenticatable = [:database]` will 60 | # enable it only for database authentication. The supported strategies are: 61 | # :database = Support basic authentication with authentication key + password 62 | # config.http_authenticatable = false 63 | 64 | # If http headers should be returned for AJAX requests. True by default. 65 | # config.http_authenticatable_on_xhr = true 66 | 67 | # The realm used in Http Basic Authentication. 'Application' by default. 68 | # config.http_authentication_realm = 'Application' 69 | 70 | # It will change confirmation, password recovery and other workflows 71 | # to behave the same regardless if the e-mail provided was right or wrong. 72 | # Does not affect registerable. 73 | # config.paranoid = true 74 | 75 | # By default Devise will store the user in session. You can skip storage for 76 | # particular strategies by setting this option. 77 | # Notice that if you are skipping storage for all authentication paths, you 78 | # may want to disable generating routes to Devise's sessions controller by 79 | # passing skip: :sessions to `devise_for` in your config/routes.rb 80 | config.skip_session_storage = [:http_auth] 81 | 82 | # By default, Devise cleans up the CSRF token on authentication to 83 | # avoid CSRF token fixation attacks. This means that, when using AJAX 84 | # requests for sign in and sign up, you need to get a new CSRF token 85 | # from the server. You can disable this option at your own risk. 86 | # config.clean_up_csrf_token_on_authentication = true 87 | 88 | # ==> Configuration for :database_authenticatable 89 | # For bcrypt, this is the cost for hashing the password and defaults to 10. If 90 | # using other encryptors, it sets how many times you want the password re-encrypted. 91 | # 92 | # Limiting the stretches to just one in testing will increase the performance of 93 | # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use 94 | # a value less than 10 in other environments. Note that, for bcrypt (the default 95 | # encryptor), the cost increases exponentially with the number of stretches (e.g. 96 | # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation). 97 | config.stretches = Rails.env.test? ? 1 : 10 98 | 99 | # Setup a pepper to generate the encrypted password. 100 | # config.pepper = '2ca3a278b8fe99e1a0a8aa3157f92cd2a7a6896bfd51e2626face439974a30593278269f7f96e7a90a7b17b90bd1f800fd8b4b4fe3b94ced215d7626ca6cacc3' 101 | 102 | # ==> Configuration for :confirmable 103 | # A period that the user is allowed to access the website even without 104 | # confirming their account. For instance, if set to 2.days, the user will be 105 | # able to access the website for two days without confirming their account, 106 | # access will be blocked just in the third day. Default is 0.days, meaning 107 | # the user cannot access the website without confirming their account. 108 | # config.allow_unconfirmed_access_for = 2.days 109 | 110 | # A period that the user is allowed to confirm their account before their 111 | # token becomes invalid. For example, if set to 3.days, the user can confirm 112 | # their account within 3 days after the mail was sent, but on the fourth day 113 | # their account can't be confirmed with the token any more. 114 | # Default is nil, meaning there is no restriction on how long a user can take 115 | # before confirming their account. 116 | # config.confirm_within = 3.days 117 | 118 | # If true, requires any email changes to be confirmed (exactly the same way as 119 | # initial account confirmation) to be applied. Requires additional unconfirmed_email 120 | # db field (see migrations). Until confirmed, new email is stored in 121 | # unconfirmed_email column, and copied to email column on successful confirmation. 122 | config.reconfirmable = true 123 | 124 | # Defines which key will be used when confirming an account 125 | # config.confirmation_keys = [ :email ] 126 | 127 | # ==> Configuration for :rememberable 128 | # The time the user will be remembered without asking for credentials again. 129 | # config.remember_for = 2.weeks 130 | 131 | # If true, extends the user's remember period when remembered via cookie. 132 | # config.extend_remember_period = false 133 | 134 | # Options to be passed to the created cookie. For instance, you can set 135 | # secure: true in order to force SSL only cookies. 136 | # config.rememberable_options = {} 137 | 138 | # ==> Configuration for :validatable 139 | # Range for password length. 140 | config.password_length = 8..128 141 | 142 | # Email regex used to validate email formats. It simply asserts that 143 | # one (and only one) @ exists in the given string. This is mainly 144 | # to give user feedback and not to assert the e-mail validity. 145 | # config.email_regexp = /\A[^@]+@[^@]+\z/ 146 | 147 | # ==> Configuration for :timeoutable 148 | # The time you want to timeout the user session without activity. After this 149 | # time the user will be asked for credentials again. Default is 30 minutes. 150 | # config.timeout_in = 30.minutes 151 | 152 | # If true, expires auth token on session timeout. 153 | # config.expire_auth_token_on_timeout = false 154 | 155 | # ==> Configuration for :lockable 156 | # Defines which strategy will be used to lock an account. 157 | # :failed_attempts = Locks an account after a number of failed attempts to sign in. 158 | # :none = No lock strategy. You should handle locking by yourself. 159 | # config.lock_strategy = :failed_attempts 160 | 161 | # Defines which key will be used when locking and unlocking an account 162 | # config.unlock_keys = [ :email ] 163 | 164 | # Defines which strategy will be used to unlock an account. 165 | # :email = Sends an unlock link to the user email 166 | # :time = Re-enables login after a certain amount of time (see :unlock_in below) 167 | # :both = Enables both strategies 168 | # :none = No unlock strategy. You should handle unlocking by yourself. 169 | # config.unlock_strategy = :both 170 | 171 | # Number of authentication tries before locking an account if lock_strategy 172 | # is failed attempts. 173 | # config.maximum_attempts = 20 174 | 175 | # Time interval to unlock the account if :time is enabled as unlock_strategy. 176 | # config.unlock_in = 1.hour 177 | 178 | # Warn on the last attempt before the account is locked. 179 | # config.last_attempt_warning = false 180 | 181 | # ==> Configuration for :recoverable 182 | # 183 | # Defines which key will be used when recovering the password for an account 184 | # config.reset_password_keys = [ :email ] 185 | 186 | # Time interval you can reset your password with a reset password key. 187 | # Don't put a too small interval or your users won't have the time to 188 | # change their passwords. 189 | config.reset_password_within = 6.hours 190 | 191 | # ==> Configuration for :encryptable 192 | # Allow you to use another encryption algorithm besides bcrypt (default). You can use 193 | # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1, 194 | # :authlogic_sha512 (then you should set stretches above to 20 for default behavior) 195 | # and :restful_authentication_sha1 (then you should set stretches to 10, and copy 196 | # REST_AUTH_SITE_KEY to pepper). 197 | # 198 | # Require the `devise-encryptable` gem when using anything other than bcrypt 199 | # config.encryptor = :sha512 200 | 201 | # ==> Scopes configuration 202 | # Turn scoped views on. Before rendering "sessions/new", it will first check for 203 | # "users/sessions/new". It's turned off by default because it's slower if you 204 | # are using only default views. 205 | # config.scoped_views = false 206 | 207 | # Configure the default scope given to Warden. By default it's the first 208 | # devise role declared in your routes (usually :user). 209 | # config.default_scope = :user 210 | 211 | # Set this configuration to false if you want /users/sign_out to sign out 212 | # only the current scope. By default, Devise signs out all scopes. 213 | # config.sign_out_all_scopes = true 214 | 215 | # ==> Navigation configuration 216 | # Lists the formats that should be treated as navigational. Formats like 217 | # :html, should redirect to the sign in page when the user does not have 218 | # access, but formats like :xml or :json, should return 401. 219 | # 220 | # If you have any extra navigational formats, like :iphone or :mobile, you 221 | # should add them to the navigational formats lists. 222 | # 223 | # The "*/*" below is required to match Internet Explorer requests. 224 | # config.navigational_formats = ['*/*', :html] 225 | 226 | # The default HTTP method used to sign out a resource. Default is :delete. 227 | config.sign_out_via = :delete 228 | 229 | # ==> OmniAuth 230 | # Add a new OmniAuth provider. Check the wiki for more information on setting 231 | # up on your models and hooks. 232 | # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' 233 | 234 | # ==> Warden configuration 235 | # If you want to use other strategies, that are not supported by Devise, or 236 | # change the failure app, you can configure them inside the config.warden block. 237 | # 238 | # config.warden do |manager| 239 | # manager.intercept_401 = false 240 | # manager.default_strategies(scope: :user).unshift :some_external_strategy 241 | # end 242 | 243 | # ==> Mountable engine configurations 244 | # When using Devise inside an engine, let's call it `MyEngine`, and this engine 245 | # is mountable, there are some extra configurations to be taken into account. 246 | # The following options are available, assuming the engine is mounted as: 247 | # 248 | # mount MyEngine, at: '/my_engine' 249 | # 250 | # The router that invoked `devise_for`, in the example above, would be: 251 | # config.router_name = :my_engine 252 | # 253 | # When using omniauth, Devise cannot automatically set Omniauth path, 254 | # so you need to do it manually. For the users scope, it would be: 255 | # config.omniauth_path_prefix = '/my_engine/users/auth' 256 | end 257 | --------------------------------------------------------------------------------