first draft (not yet fully functional) of the I18n feature
This commit is contained in:
parent
e0b9367f10
commit
c68eb321ff
1
Gemfile
1
Gemfile
@ -11,6 +11,7 @@ gem 'devise', '1.3.4'
|
||||
gem 'devise_bushido_authenticatable', '1.0.0.alpha10', :require => 'devise_cas_authenticatable'
|
||||
|
||||
gem 'mongoid', '~> 2.0.2'
|
||||
gem 'mongoid_i18n', :require => 'mongoid/i18n'
|
||||
gem 'bson_ext', '~> 1.3.0'
|
||||
gem 'locomotive_mongoid_acts_as_tree', '0.1.5.7', :require => 'mongoid_acts_as_tree'
|
||||
gem 'will_paginate', '~> 3.0.0'
|
||||
|
@ -180,6 +180,9 @@ GEM
|
||||
activemodel (~> 3.0)
|
||||
mongo (~> 1.3)
|
||||
tzinfo (~> 0.3.22)
|
||||
mongoid_i18n (0.3.1)
|
||||
bson_ext
|
||||
mongoid (>= 2.0.0)
|
||||
net-ssh (2.1.4)
|
||||
nokogiri (1.5.0)
|
||||
open4 (1.1.0)
|
||||
@ -321,6 +324,7 @@ DEPENDENCIES
|
||||
mimetype-fu
|
||||
mocha!
|
||||
mongoid (~> 2.0.2)
|
||||
mongoid_i18n
|
||||
pickle
|
||||
rack-cache
|
||||
rails (= 3.0.9)
|
||||
|
11
app/cells/admin/site_locale_picker/show.html.haml
Normal file
11
app/cells/admin/site_locale_picker/show.html.haml
Normal file
@ -0,0 +1,11 @@
|
||||
#site-locale-picker
|
||||
%span.hand
|
||||
|
||||
|
||||
%ul
|
||||
- @locales.each_with_index do |locale, index|
|
||||
%li{ :class => "#{'first' if index == 0}" }
|
||||
|
||||
= image_tag "admin/icons/flags/#{locale}.png", :class => 'flag'
|
||||
|
||||
%span.text= locale
|
15
app/cells/admin/site_locale_picker_cell.rb
Normal file
15
app/cells/admin/site_locale_picker_cell.rb
Normal file
@ -0,0 +1,15 @@
|
||||
class Admin::SiteLocalePickerCell < Cell::Base
|
||||
|
||||
def show(args)
|
||||
site = args[:site]
|
||||
locale = args[:locale].to_s
|
||||
|
||||
if site.locales.empty? || site.locales.size < 2
|
||||
''
|
||||
else
|
||||
@locales = [locale] + (site.locales - [locale])
|
||||
render
|
||||
end
|
||||
end
|
||||
|
||||
end
|
@ -15,6 +15,8 @@ module Admin
|
||||
|
||||
before_filter :set_locale
|
||||
|
||||
before_filter :set_site_locale
|
||||
|
||||
helper_method :sections, :current_site_url, :site_url, :page_url, :current_ability
|
||||
|
||||
# https://rails.lighthouseapp.com/projects/8994/tickets/1905-apphelpers-within-plugin-not-being-mixed-in
|
||||
@ -71,7 +73,21 @@ module Admin
|
||||
end
|
||||
|
||||
def set_locale
|
||||
I18n.locale = current_admin.locale rescue Locomotive.config.default_locale
|
||||
I18n.locale = current_admin.locale rescue Locomotive.config.default_locale # for the back-office
|
||||
end
|
||||
|
||||
def set_site_locale
|
||||
I18n.default_site_locale = current_site.default_locale
|
||||
|
||||
if params[:site_locale].present?
|
||||
session[:site_locale] = params[:site_locale]
|
||||
end
|
||||
|
||||
unless current_site.locales.include?(session[:site_locale])
|
||||
session[:site_locale] = current_site.default_locale
|
||||
end
|
||||
|
||||
I18n.site_locale = session[:site_locale]
|
||||
end
|
||||
|
||||
# ___ site/page urls builder ___
|
||||
|
@ -30,4 +30,7 @@ module Admin::SitesHelper
|
||||
Locomotive.config.multi_sites?
|
||||
end
|
||||
|
||||
def ordered_site_locales(site)
|
||||
site.locales + (Locomotive.config.site_locales - site.locales)
|
||||
end
|
||||
end
|
||||
|
@ -2,6 +2,7 @@ class ContentInstance
|
||||
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
include Mongoid::I18n
|
||||
|
||||
## extensions ##
|
||||
include CustomFields::ProxyClassEnabler
|
||||
|
@ -4,9 +4,9 @@ module Extensions
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
field :seo_title, :type => String
|
||||
field :meta_keywords, :type => String
|
||||
field :meta_description, :type => String
|
||||
localized_field :seo_title
|
||||
localized_field :meta_keywords
|
||||
localized_field :meta_description
|
||||
end
|
||||
|
||||
end # Seo
|
||||
|
@ -1,6 +1,7 @@
|
||||
class Page
|
||||
|
||||
include Locomotive::Mongoid::Document
|
||||
include Mongoid::I18n
|
||||
|
||||
## Extensions ##
|
||||
include Extensions::Page::Tree
|
||||
@ -13,9 +14,9 @@ class Page
|
||||
include Extensions::Shared::Seo
|
||||
|
||||
## fields ##
|
||||
field :title
|
||||
field :slug
|
||||
field :fullpath
|
||||
localized_field :title
|
||||
localized_field :slug
|
||||
localized_field :fullpath
|
||||
field :raw_template
|
||||
field :published, :type => Boolean, :default => false
|
||||
field :cache_strategy, :default => 'none'
|
||||
@ -61,9 +62,9 @@ class Page
|
||||
self.index? || self.not_found?
|
||||
end
|
||||
|
||||
def fullpath(force = false)
|
||||
if read_attribute(:fullpath).present? && !force
|
||||
return read_attribute(:fullpath)
|
||||
def fullpath_with_building(force = false)
|
||||
if self.fullpath_without_building.present? && !force
|
||||
self.fullpath_without_building
|
||||
end
|
||||
|
||||
if self.index? || self.not_found?
|
||||
@ -75,6 +76,8 @@ class Page
|
||||
end
|
||||
end
|
||||
|
||||
alias_method_chain :fullpath, :building
|
||||
|
||||
def with_cache?
|
||||
self.cache_strategy != 'none'
|
||||
end
|
||||
|
@ -1,6 +1,7 @@
|
||||
class Site
|
||||
|
||||
include Locomotive::Mongoid::Document
|
||||
include Mongoid::I18n
|
||||
|
||||
## Extensions ##
|
||||
extend Extensions::Site::SubdomainDomains
|
||||
@ -10,6 +11,7 @@ class Site
|
||||
## fields ##
|
||||
field :name
|
||||
field :robots_txt
|
||||
field :locales, :type => Array, :default => []
|
||||
|
||||
## associations ##
|
||||
references_many :pages, :validate => false
|
||||
@ -32,6 +34,10 @@ class Site
|
||||
|
||||
## methods ##
|
||||
|
||||
def default_locale
|
||||
self.locales.first || Locomotive.config.site_locales.first
|
||||
end
|
||||
|
||||
def all_pages_in_once
|
||||
Page.quick_tree(self)
|
||||
end
|
||||
|
@ -9,6 +9,17 @@
|
||||
= f.input :meta_keywords
|
||||
= f.input :meta_description
|
||||
|
||||
- if can?(:manage, current_site)
|
||||
= f.foldable_inputs :name => :locales, :class => 'language locales' do
|
||||
= f.custom_input :locales, { :css => 'full', :with_label => false } do
|
||||
#locales
|
||||
- ordered_site_locales(@site).each do |locale|
|
||||
%span
|
||||
= check_box_tag 'site[locales][]', locale, @site.locales.include?(locale), :id => "site-locales-#{locale}"
|
||||
%label{ :for => "site-locales-#{locale}" }
|
||||
= image_tag "admin/icons/flags/#{locale}.png"
|
||||
= t("admin.locales.#{locale}")
|
||||
|
||||
- if can?(:point, Site)
|
||||
- if manage_subdomain_or_domains?
|
||||
= f.foldable_inputs :name => :access_points, :class => 'editable-list off' do
|
||||
|
@ -3,6 +3,9 @@
|
||||
- content_for :submenu do
|
||||
= render_cell 'admin/settings_menu', :show
|
||||
|
||||
- content_for :actions do
|
||||
= render_cell 'admin/site_locale_picker', :show, :site => current_site, :locale => I18n.site_locale
|
||||
|
||||
- if can?(:manage, @site)
|
||||
- content_for :buttons do
|
||||
= admin_button_tag :export, new_admin_export_url, :class => 'new'
|
||||
|
@ -40,8 +40,7 @@
|
||||
= f.radio_button :locale, locale
|
||||
%label{ :for => "my_account_locale_#{locale.downcase}" }
|
||||
= image_tag "admin/icons/flags/#{locale}.png"
|
||||
= t(".#{locale}")
|
||||
/
|
||||
= t("admin.locales.#{locale}")
|
||||
|
||||
|
||||
= render 'admin/shared/form_actions', :button_label => :update
|
||||
|
@ -1,2 +1,4 @@
|
||||
- if can? :manage, ContentType
|
||||
= link_to content_tag(:em) + content_tag(:span, t('admin.content_types.index.new')), new_admin_content_type_url
|
||||
|
||||
= render_cell 'admin/site_locale_picker', :show, :site => current_site, :locale => I18n.site_locale
|
@ -93,6 +93,7 @@ stylesheets:
|
||||
- public/stylesheets/admin/formtastic_changes.css
|
||||
- public/stylesheets/admin/assets.css
|
||||
- public/stylesheets/admin/sites_picker.css
|
||||
- public/stylesheets/admin/site_locale_picker.css
|
||||
- public/stylesheets/admin/application.css
|
||||
- public/stylesheets/admin/safari.css
|
||||
- public/stylesheets/admin/guiders-1.1.0.css
|
||||
|
@ -1,5 +1,14 @@
|
||||
de:
|
||||
admin:
|
||||
locales:
|
||||
en: Englisch
|
||||
de: Deutsch
|
||||
fr: Französisch
|
||||
pt-BR: "Bras. Portugisisch"
|
||||
it: "Italienisch"
|
||||
nl: "Holländer"
|
||||
es: "Spanisch"
|
||||
|
||||
buttons:
|
||||
login: Einloggen
|
||||
send_password: Senden
|
||||
@ -157,13 +166,6 @@ de:
|
||||
edit:
|
||||
help: "Deinen Namen kannst du durch darauf klicken ändern."
|
||||
new_site: Neue Webseite
|
||||
en: Englisch
|
||||
de: Deutsch
|
||||
fr: Französisch
|
||||
pt-BR: "Bras. Portugisisch"
|
||||
it: "Italienisch"
|
||||
nl: "Holländer"
|
||||
es: "Spanisch"
|
||||
ask_for_name: "Bitte gib deinen neuen Namen an"
|
||||
|
||||
theme_assets:
|
||||
|
@ -1,5 +1,14 @@
|
||||
en:
|
||||
admin:
|
||||
locales:
|
||||
en: English
|
||||
de: German
|
||||
fr: French
|
||||
pt-BR: "Brazilian Portuguese"
|
||||
it: Italian
|
||||
nl: Dutch
|
||||
es: Spanish
|
||||
|
||||
buttons:
|
||||
login: Log in
|
||||
send_password: Send
|
||||
@ -168,13 +177,6 @@ en:
|
||||
edit:
|
||||
help: "Your name can be updated by clicking it. To apply your changes, click on the \"Save\" button."
|
||||
new_site: new site
|
||||
en: English
|
||||
de: German
|
||||
fr: French
|
||||
pt-BR: "Brazilian Portuguese"
|
||||
it: Italian
|
||||
nl: Dutch
|
||||
es: Spanish
|
||||
ask_for_name: "Please type your new name"
|
||||
|
||||
theme_assets:
|
||||
|
@ -1,5 +1,14 @@
|
||||
fr:
|
||||
admin:
|
||||
locales:
|
||||
en: en Anglais
|
||||
de: en Allemand
|
||||
fr: en Français
|
||||
pt-BR: "en Portugais"
|
||||
it: "en Italien"
|
||||
nl: "en Hollandais"
|
||||
es: en Espagnol
|
||||
|
||||
errors:
|
||||
"500":
|
||||
title: Erreur applicative
|
||||
@ -169,13 +178,6 @@ fr:
|
||||
edit:
|
||||
help: "Votre nom est modifiable en cliquant dessus. Pour appliquer votre modification, cliquez après sur le bouton \"Modifier\""
|
||||
new_site: nouveau site
|
||||
en: en Anglais
|
||||
de: en Allemand
|
||||
fr: en Français
|
||||
pt-BR: "en Portugais"
|
||||
it: "en Italien"
|
||||
nl: "en Hollandais"
|
||||
es: en Espagnol
|
||||
ask_for_name: "Veuillez entrer le nouveau nom"
|
||||
|
||||
theme_assets:
|
||||
|
@ -10,6 +10,7 @@ en:
|
||||
raw_template: Template
|
||||
credentials: Credentials
|
||||
language: Language
|
||||
locales: Locales
|
||||
sites: Sites
|
||||
access_points: Access points
|
||||
memberships: Accounts
|
||||
@ -67,6 +68,7 @@ en:
|
||||
seo_title: "Define a global value here which should be used as the value for the title tag in the head section."
|
||||
meta_keywords: "Meta keywords used within the head tag of the page. They are separated by a comma. Required for SEO."
|
||||
meta_description: "Meta description used within the head tag of the page. Required for SEO."
|
||||
locales: "Drag&drop a flag to the first position to make it the default one."
|
||||
domain_name: "ex: locomotiveapp.org"
|
||||
robots_txt: "Content of the <span class='code'>/robots.txt</span> file. Check the following <a href='http://www.w3.org/TR/html4/appendix/notes.html#h-B.4.1.1'>url</a> for more information."
|
||||
theme_asset:
|
||||
|
30
doc/TODO
30
doc/TODO
@ -1,5 +1,35 @@
|
||||
BOARD:
|
||||
|
||||
- i18n (in progress)
|
||||
x site locales
|
||||
x model
|
||||
x ui
|
||||
x locale picker
|
||||
x patches
|
||||
x i18n
|
||||
x mongoid-i18n
|
||||
x rendering engine
|
||||
x get locale
|
||||
x render the right version
|
||||
- contents
|
||||
x store the site locale value
|
||||
- pages
|
||||
x title / slug / fullpath / seo
|
||||
- template ?
|
||||
- editable contents
|
||||
- custom contents
|
||||
- snippets
|
||||
x site
|
||||
x seo
|
||||
x locale picker
|
||||
- liquid tags:
|
||||
- link_to (new)
|
||||
- nav
|
||||
- locale switcher
|
||||
- others ? -
|
||||
- other problems to solve:
|
||||
- If you create a new page it shall always be created in the default_language, not depending on the used language in the backend.
|
||||
|
||||
BACKLOG:
|
||||
|
||||
- custom_fields:
|
||||
|
@ -22,6 +22,7 @@ require 'locomotive/delayed_job'
|
||||
require 'locomotive/middlewares'
|
||||
require 'locomotive/session_store'
|
||||
require 'locomotive/hosting'
|
||||
require 'locomotive/i18n'
|
||||
|
||||
module Locomotive
|
||||
|
||||
|
@ -8,6 +8,7 @@ module Locomotive
|
||||
# :forbidden_paths => %w{layouts snippets stylesheets javascripts assets admin system api},
|
||||
:reserved_slugs => %w{stylesheets javascripts assets admin images api pages edit},
|
||||
:locales => %w{en de fr pt-BR it nl es},
|
||||
:site_locales => %w{en de fr pt-BR it nl es},
|
||||
:cookie_key => '_locomotive_session',
|
||||
:enable_logs => false,
|
||||
:hosting => :auto,
|
||||
|
@ -5,6 +5,7 @@ require 'json/pure'
|
||||
require 'devise'
|
||||
require 'mongoid'
|
||||
require 'mongoid_acts_as_tree'
|
||||
require 'mongoid/i18n'
|
||||
require 'will_paginate'
|
||||
require 'haml'
|
||||
require 'liquid'
|
||||
|
92
lib/locomotive/i18n.rb
Normal file
92
lib/locomotive/i18n.rb
Normal file
@ -0,0 +1,92 @@
|
||||
## patches for the i18n support (aka multi languages support)
|
||||
require 'i18n'
|
||||
|
||||
module I18n
|
||||
class Config
|
||||
def site_locale
|
||||
@site_locale ||= default_site_locale
|
||||
end
|
||||
|
||||
def site_locale=(site_locale)
|
||||
@site_locale = site_locale.to_sym rescue nil
|
||||
end
|
||||
|
||||
def default_site_locale
|
||||
@@default_site_locale ||= :en
|
||||
end
|
||||
|
||||
def default_site_locale=(site_locale)
|
||||
@@default_site_locale = site_locale.to_sym rescue nil
|
||||
end
|
||||
end
|
||||
|
||||
class << self
|
||||
# Write methods which delegates to the configuration object
|
||||
%w(site_locale default_site_locale).each do |method|
|
||||
module_eval <<-DELEGATORS, __FILE__, __LINE__ + 1
|
||||
def #{method}
|
||||
config.#{method}
|
||||
end
|
||||
|
||||
def #{method}=(value)
|
||||
config.#{method} = (value)
|
||||
end
|
||||
DELEGATORS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: fork https://github.com/Papipo/mongoid_i18n
|
||||
module Mongoid
|
||||
module I18n
|
||||
module ClassMethods
|
||||
def create_accessors(name, meth, options = {})
|
||||
if options[:type] == LocalizedField
|
||||
if options[:use_default_if_empty] != false # nil or true
|
||||
define_method(meth) do
|
||||
value = read_attribute(name)
|
||||
if value.is_a?(Hash)
|
||||
value[::I18n.site_locale.to_s] || value[::I18n.default_site_locale.to_s] rescue ''
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
else
|
||||
define_method(meth) do
|
||||
value = read_attribute(name)
|
||||
if value.is_a?(Hash)
|
||||
read_attribute(name)[::I18n.site_locale.to_s] rescue ''
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
end
|
||||
define_method("#{meth}=") do |value|
|
||||
puts "@attributes[name].present? = #{@attributes[name].present?.inspect} / !@attributes[name].is_a?(Hash) #{(!@attributes[name].is_a?(Hash)).inspect}"
|
||||
if !@attributes[name].nil? && !@attributes[name].is_a?(Hash)
|
||||
@attributes[name] = { ::I18n.default_site_locale.to_s => @attributes[name] }
|
||||
end
|
||||
|
||||
puts "value = #{value.inspect} / #{meth}"
|
||||
|
||||
value = if value.is_a?(Hash)
|
||||
(@attributes[name] || {}).merge(value)
|
||||
else
|
||||
(@attributes[name] || {}).merge(::I18n.site_locale.to_s => value)
|
||||
end
|
||||
value = value.delete_if { |key, value| value.blank? } if options[:clear_empty_values] != false
|
||||
write_attribute(name, value)
|
||||
end
|
||||
define_method("#{meth}_translations") { read_attribute(name) }
|
||||
if options[:clear_empty_values] != false
|
||||
define_method("#{meth}_translations=") { |value| write_attribute(name, value.delete_if { |key, value| value.blank? }) }
|
||||
else
|
||||
define_method("#{meth}_translations=") { |value| write_attribute(name, value) }
|
||||
end
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -33,6 +33,12 @@ module Locomotive
|
||||
path.gsub!(/\.[a-zA-Z][a-zA-Z0-9]{2,}$/, '') # remove the page extension
|
||||
path.gsub!(/^\//, '') # remove the leading slash
|
||||
|
||||
# extract the site locale
|
||||
if path =~ /^(#{current_site.locales.join('|')})+(\/|$)/
|
||||
I18n.site_locale = $1
|
||||
path.gsub!($1 + $2, '')
|
||||
end
|
||||
|
||||
path = 'index' if path.blank?
|
||||
|
||||
if path != 'index'
|
||||
@ -67,7 +73,10 @@ module Locomotive
|
||||
'params' => self.params,
|
||||
'url' => request.url,
|
||||
'now' => Time.now.utc,
|
||||
'today' => Date.today
|
||||
'today' => Date.today,
|
||||
'default_locale' => I18n.default_site_locale.to_s,
|
||||
'current_locale' => I18n.site_locale.to_s,
|
||||
'locales' => current_site.locales
|
||||
}
|
||||
|
||||
assigns.merge!(Locomotive.config.context_assign_extensions)
|
||||
|
@ -22,6 +22,7 @@ Gem::Specification.new do |s|
|
||||
s.add_dependency 'devise', '1.3.4'
|
||||
s.add_dependency 'devise_bushido_authenticatable', '1.0.0.alpha10'
|
||||
s.add_dependency 'mongoid', '2.0.2'
|
||||
s.add_dependency 'mongoid_i18n'
|
||||
s.add_dependency 'bson_ext', '~> 1.3.0'
|
||||
s.add_dependency 'locomotive_mongoid_acts_as_tree', '0.1.5.7'
|
||||
s.add_dependency 'will_paginate', '~> 3.0.0'
|
||||
|
@ -165,4 +165,11 @@ $(document).ready(function() {
|
||||
.trigger('refresh');
|
||||
|
||||
$('.formtastic fieldset.inputs ol li:not(.item)').last().addClass('last');
|
||||
|
||||
// site locale picker
|
||||
$('#site-locale-picker').hover(function() { $(this).addClass('open'); }, function() { $(this).removeClass('open'); })
|
||||
.find('li:gt(0)').click(function(e) {
|
||||
var locale = $(this).find('.text').html();
|
||||
addParameterToURL('site_locale', locale);
|
||||
});
|
||||
});
|
||||
|
@ -70,5 +70,6 @@ $(document).ready(function() {
|
||||
});
|
||||
}).hide();
|
||||
|
||||
|
||||
// locales
|
||||
$('#locales').sortable({ items: 'span', handle: 'label', tolerance: 'pointer', appendTo: 'body' });
|
||||
});
|
||||
|
@ -13,6 +13,27 @@ function makeSlug(val, sep) { // code largely inspired by http://www.thewebsitet
|
||||
return val.toLowerCase();
|
||||
}
|
||||
|
||||
function addParameterToURL(key, value) { // code from http://stackoverflow.com/questions/486896/adding-a-parameter-to-the-url-with-javascript
|
||||
key = encodeURIComponent(key); value = encodeURIComponent(value);
|
||||
|
||||
var kvp = document.location.search.substr(1).split('&');
|
||||
|
||||
var i = kvp.length; var x; while(i--) {
|
||||
x = kvp[i].split('=');
|
||||
|
||||
if (x[0] == key) {
|
||||
x[1] = value;
|
||||
kvp[i] = x.join('=');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < 0) { kvp[kvp.length] = [key,value].join('='); }
|
||||
|
||||
//this will reload the page, it's likely better to store this until finished
|
||||
document.location.search = kvp.join('&');
|
||||
}
|
||||
|
||||
(function() {
|
||||
String.prototype.trim = function() {
|
||||
return this.replace(/^\s+/g, '').replace(/\s+$/g, '');
|
||||
|
@ -508,7 +508,7 @@ form.formtastic fieldset ol li.has-many ul li.template span.actions button span
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
/* ___ my account ___ */
|
||||
/* ___ language / locales ___ */
|
||||
|
||||
form.formtastic fieldset.language li.full span {
|
||||
display: inline-block;
|
||||
@ -535,6 +535,14 @@ form.formtastic fieldset.language li.full span input {
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
form.formtastic fieldset.locales li.full span:first-child label {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
form.formtastic fieldset.locales p.inline-hints {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
/* ___ membership ___ */
|
||||
|
||||
form.formtastic fieldset.email li.full input {
|
||||
|
@ -107,7 +107,8 @@
|
||||
background: transparent url(/images/admin/menu/submenu/action-border.png) repeat-y left 0; }
|
||||
#submenu > .action a {
|
||||
margin-top: 18px;
|
||||
display: inline-block;
|
||||
display: block;
|
||||
float: left;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
border-radius: 16px;
|
||||
-moz-border-radius: 16px;
|
||||
|
62
public/stylesheets/admin/site_locale_picker.css
Normal file
62
public/stylesheets/admin/site_locale_picker.css
Normal file
@ -0,0 +1,62 @@
|
||||
/* ___ AUTOMATICALLY GENERATED: see admin/site_locale_picker.scss for the source file */
|
||||
/* ___ rounded ___ */
|
||||
/* ___ box shadow ___ */
|
||||
/* ___ others ___ */
|
||||
#site-locale-picker {
|
||||
position: relative;
|
||||
float: right;
|
||||
margin: 18px 0 0 10px;
|
||||
padding: 0px 25px 0 10px;
|
||||
border: 1px solid transparent;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
border-radius: 16px;
|
||||
-moz-border-radius: 16px;
|
||||
-webkit-border-radius: 16px; }
|
||||
#site-locale-picker:hover {
|
||||
border-color: black;
|
||||
border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
-webkit-border-radius: 12px; }
|
||||
#site-locale-picker .hand {
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
right: 7px;
|
||||
height: 7px;
|
||||
width: 12px;
|
||||
background: transparent url(/images/admin/menu/icons.png) no-repeat 0px -16px; }
|
||||
#site-locale-picker ul {
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding: 0px; }
|
||||
#site-locale-picker ul li {
|
||||
position: relative;
|
||||
display: none;
|
||||
margin: 5px 0;
|
||||
height: 22px;
|
||||
line-height: 20px;
|
||||
cursor: pointer; }
|
||||
#site-locale-picker ul li img.flag {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
width: 20px;
|
||||
height: 20px; }
|
||||
#site-locale-picker ul li span.text {
|
||||
position: relative;
|
||||
position: relative;
|
||||
top: -6px;
|
||||
color: #fff;
|
||||
font-size: 0.7em;
|
||||
text-shadow: 1px 1px 1px #000;
|
||||
text-transform: uppercase; }
|
||||
#site-locale-picker ul li:first-child {
|
||||
display: block;
|
||||
margin: 0px;
|
||||
cursor: default; }
|
||||
#site-locale-picker ul li:last-child {
|
||||
margin-bottom: 0px; }
|
||||
#site-locale-picker ul li:hover span.text {
|
||||
text-decoration: underline; }
|
||||
#site-locale-picker.open ul li {
|
||||
display: block; }
|
||||
#site-locale-picker.open ul li:first-child {
|
||||
margin-bottom: 5px; }
|
@ -112,7 +112,8 @@
|
||||
|
||||
a {
|
||||
margin-top: 18px;
|
||||
display: inline-block;
|
||||
display: block;
|
||||
float: left;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
@include full-rounded(16px);
|
||||
padding: 0px 10px 0 15px;
|
||||
|
105
public/stylesheets/sass/admin/site_locale_picker.scss
Normal file
105
public/stylesheets/sass/admin/site_locale_picker.scss
Normal file
@ -0,0 +1,105 @@
|
||||
/* ___ AUTOMATICALLY GENERATED: see admin/site_locale_picker.scss for the source file */
|
||||
|
||||
@import "helpers";
|
||||
|
||||
#site-locale-picker {
|
||||
|
||||
position: relative;
|
||||
|
||||
float: right;
|
||||
|
||||
margin: 18px 0 0 10px;
|
||||
padding: 0px 25px 0 10px;
|
||||
|
||||
border: 1px solid transparent;
|
||||
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
@include full-rounded(16px);
|
||||
|
||||
&:hover {
|
||||
border-color: rgba(0, 0, 0, 1);
|
||||
@include full-rounded(12px);
|
||||
}
|
||||
|
||||
.hand {
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
right: 7px;
|
||||
|
||||
height: 7px;
|
||||
width: 12px;
|
||||
|
||||
background: transparent url(/images/admin/menu/icons.png) no-repeat 0px -16px;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
|
||||
display: none;
|
||||
|
||||
margin: 5px 0;
|
||||
|
||||
height: 22px;
|
||||
line-height: 20px;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
img.flag {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
span.text {
|
||||
position: relative;
|
||||
|
||||
position: relative;
|
||||
top: -6px;
|
||||
|
||||
color: #fff;
|
||||
font-size: 0.7em;
|
||||
text-shadow: 1px 1px 1px #000;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
display: block;
|
||||
margin: 0px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
span.text {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
&.open {
|
||||
ul {
|
||||
li {
|
||||
display: block;
|
||||
|
||||
&:first-child {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user