first draft (not yet fully functional) of the I18n feature

This commit is contained in:
did 2011-08-17 04:23:14 +02:00
parent e0b9367f10
commit c68eb321ff
34 changed files with 464 additions and 39 deletions

View File

@ -11,6 +11,7 @@ gem 'devise', '1.3.4'
gem 'devise_bushido_authenticatable', '1.0.0.alpha10', :require => 'devise_cas_authenticatable' gem 'devise_bushido_authenticatable', '1.0.0.alpha10', :require => 'devise_cas_authenticatable'
gem 'mongoid', '~> 2.0.2' gem 'mongoid', '~> 2.0.2'
gem 'mongoid_i18n', :require => 'mongoid/i18n'
gem 'bson_ext', '~> 1.3.0' gem 'bson_ext', '~> 1.3.0'
gem 'locomotive_mongoid_acts_as_tree', '0.1.5.7', :require => 'mongoid_acts_as_tree' gem 'locomotive_mongoid_acts_as_tree', '0.1.5.7', :require => 'mongoid_acts_as_tree'
gem 'will_paginate', '~> 3.0.0' gem 'will_paginate', '~> 3.0.0'

View File

@ -180,6 +180,9 @@ GEM
activemodel (~> 3.0) activemodel (~> 3.0)
mongo (~> 1.3) mongo (~> 1.3)
tzinfo (~> 0.3.22) tzinfo (~> 0.3.22)
mongoid_i18n (0.3.1)
bson_ext
mongoid (>= 2.0.0)
net-ssh (2.1.4) net-ssh (2.1.4)
nokogiri (1.5.0) nokogiri (1.5.0)
open4 (1.1.0) open4 (1.1.0)
@ -321,6 +324,7 @@ DEPENDENCIES
mimetype-fu mimetype-fu
mocha! mocha!
mongoid (~> 2.0.2) mongoid (~> 2.0.2)
mongoid_i18n
pickle pickle
rack-cache rack-cache
rails (= 3.0.9) rails (= 3.0.9)

View 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

View 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

View File

@ -15,6 +15,8 @@ module Admin
before_filter :set_locale before_filter :set_locale
before_filter :set_site_locale
helper_method :sections, :current_site_url, :site_url, :page_url, :current_ability 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 # https://rails.lighthouseapp.com/projects/8994/tickets/1905-apphelpers-within-plugin-not-being-mixed-in
@ -71,7 +73,21 @@ module Admin
end end
def set_locale 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 end
# ___ site/page urls builder ___ # ___ site/page urls builder ___

View File

@ -30,4 +30,7 @@ module Admin::SitesHelper
Locomotive.config.multi_sites? Locomotive.config.multi_sites?
end end
def ordered_site_locales(site)
site.locales + (Locomotive.config.site_locales - site.locales)
end
end end

View File

@ -2,6 +2,7 @@ class ContentInstance
include Mongoid::Document include Mongoid::Document
include Mongoid::Timestamps include Mongoid::Timestamps
include Mongoid::I18n
## extensions ## ## extensions ##
include CustomFields::ProxyClassEnabler include CustomFields::ProxyClassEnabler

View File

@ -4,9 +4,9 @@ module Extensions
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
field :seo_title, :type => String localized_field :seo_title
field :meta_keywords, :type => String localized_field :meta_keywords
field :meta_description, :type => String localized_field :meta_description
end end
end # Seo end # Seo

View File

@ -1,6 +1,7 @@
class Page class Page
include Locomotive::Mongoid::Document include Locomotive::Mongoid::Document
include Mongoid::I18n
## Extensions ## ## Extensions ##
include Extensions::Page::Tree include Extensions::Page::Tree
@ -13,9 +14,9 @@ class Page
include Extensions::Shared::Seo include Extensions::Shared::Seo
## fields ## ## fields ##
field :title localized_field :title
field :slug localized_field :slug
field :fullpath localized_field :fullpath
field :raw_template field :raw_template
field :published, :type => Boolean, :default => false field :published, :type => Boolean, :default => false
field :cache_strategy, :default => 'none' field :cache_strategy, :default => 'none'
@ -61,9 +62,9 @@ class Page
self.index? || self.not_found? self.index? || self.not_found?
end end
def fullpath(force = false) def fullpath_with_building(force = false)
if read_attribute(:fullpath).present? && !force if self.fullpath_without_building.present? && !force
return read_attribute(:fullpath) self.fullpath_without_building
end end
if self.index? || self.not_found? if self.index? || self.not_found?
@ -75,6 +76,8 @@ class Page
end end
end end
alias_method_chain :fullpath, :building
def with_cache? def with_cache?
self.cache_strategy != 'none' self.cache_strategy != 'none'
end end

View File

@ -1,6 +1,7 @@
class Site class Site
include Locomotive::Mongoid::Document include Locomotive::Mongoid::Document
include Mongoid::I18n
## Extensions ## ## Extensions ##
extend Extensions::Site::SubdomainDomains extend Extensions::Site::SubdomainDomains
@ -10,6 +11,7 @@ class Site
## fields ## ## fields ##
field :name field :name
field :robots_txt field :robots_txt
field :locales, :type => Array, :default => []
## associations ## ## associations ##
references_many :pages, :validate => false references_many :pages, :validate => false
@ -32,6 +34,10 @@ class Site
## methods ## ## methods ##
def default_locale
self.locales.first || Locomotive.config.site_locales.first
end
def all_pages_in_once def all_pages_in_once
Page.quick_tree(self) Page.quick_tree(self)
end end

View File

@ -9,6 +9,17 @@
= f.input :meta_keywords = f.input :meta_keywords
= f.input :meta_description = 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 can?(:point, Site)
- if manage_subdomain_or_domains? - if manage_subdomain_or_domains?
= f.foldable_inputs :name => :access_points, :class => 'editable-list off' do = f.foldable_inputs :name => :access_points, :class => 'editable-list off' do

View File

@ -2,6 +2,9 @@
- content_for :submenu do - content_for :submenu do
= render_cell 'admin/settings_menu', :show = 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) - if can?(:manage, @site)
- content_for :buttons do - content_for :buttons do

View File

@ -40,8 +40,7 @@
= f.radio_button :locale, locale = f.radio_button :locale, locale
%label{ :for => "my_account_locale_#{locale.downcase}" } %label{ :for => "my_account_locale_#{locale.downcase}" }
= image_tag "admin/icons/flags/#{locale}.png" = image_tag "admin/icons/flags/#{locale}.png"
= t(".#{locale}") = t("admin.locales.#{locale}")
/ &nbsp;
= render 'admin/shared/form_actions', :button_label => :update = render 'admin/shared/form_actions', :button_label => :update

View File

@ -1,2 +1,4 @@
- if can? :manage, ContentType - if can? :manage, ContentType
= link_to content_tag(:em) + content_tag(:span, t('admin.content_types.index.new')), new_admin_content_type_url = 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

View File

@ -93,6 +93,7 @@ stylesheets:
- public/stylesheets/admin/formtastic_changes.css - public/stylesheets/admin/formtastic_changes.css
- public/stylesheets/admin/assets.css - public/stylesheets/admin/assets.css
- public/stylesheets/admin/sites_picker.css - public/stylesheets/admin/sites_picker.css
- public/stylesheets/admin/site_locale_picker.css
- public/stylesheets/admin/application.css - public/stylesheets/admin/application.css
- public/stylesheets/admin/safari.css - public/stylesheets/admin/safari.css
- public/stylesheets/admin/guiders-1.1.0.css - public/stylesheets/admin/guiders-1.1.0.css

View File

@ -1,5 +1,14 @@
de: de:
admin: admin:
locales:
en: Englisch
de: Deutsch
fr: Französisch
pt-BR: "Bras. Portugisisch"
it: "Italienisch"
nl: "Holländer"
es: "Spanisch"
buttons: buttons:
login: Einloggen login: Einloggen
send_password: Senden send_password: Senden
@ -157,13 +166,6 @@ de:
edit: edit:
help: "Deinen Namen kannst du durch darauf klicken ändern." help: "Deinen Namen kannst du durch darauf klicken ändern."
new_site: Neue Webseite 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" ask_for_name: "Bitte gib deinen neuen Namen an"
theme_assets: theme_assets:

View File

@ -1,5 +1,14 @@
en: en:
admin: admin:
locales:
en: English
de: German
fr: French
pt-BR: "Brazilian Portuguese"
it: Italian
nl: Dutch
es: Spanish
buttons: buttons:
login: Log in login: Log in
send_password: Send send_password: Send
@ -168,13 +177,6 @@ en:
edit: edit:
help: "Your name can be updated by clicking it. To apply your changes, click on the \"Save\" button." help: "Your name can be updated by clicking it. To apply your changes, click on the \"Save\" button."
new_site: new site 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" ask_for_name: "Please type your new name"
theme_assets: theme_assets:

View File

@ -1,5 +1,14 @@
fr: fr:
admin: 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: errors:
"500": "500":
title: Erreur applicative title: Erreur applicative
@ -169,13 +178,6 @@ fr:
edit: edit:
help: "Votre nom est modifiable en cliquant dessus. Pour appliquer votre modification, cliquez après sur le bouton \"Modifier\"" help: "Votre nom est modifiable en cliquant dessus. Pour appliquer votre modification, cliquez après sur le bouton \"Modifier\""
new_site: nouveau site 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" ask_for_name: "Veuillez entrer le nouveau nom"
theme_assets: theme_assets:

View File

@ -10,6 +10,7 @@ en:
raw_template: Template raw_template: Template
credentials: Credentials credentials: Credentials
language: Language language: Language
locales: Locales
sites: Sites sites: Sites
access_points: Access points access_points: Access points
memberships: Accounts 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." 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_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." 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" 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." 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: theme_asset:

View File

@ -1,5 +1,35 @@
BOARD: 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: BACKLOG:
- custom_fields: - custom_fields:

View File

@ -22,6 +22,7 @@ require 'locomotive/delayed_job'
require 'locomotive/middlewares' require 'locomotive/middlewares'
require 'locomotive/session_store' require 'locomotive/session_store'
require 'locomotive/hosting' require 'locomotive/hosting'
require 'locomotive/i18n'
module Locomotive module Locomotive

View File

@ -8,6 +8,7 @@ module Locomotive
# :forbidden_paths => %w{layouts snippets stylesheets javascripts assets admin system api}, # :forbidden_paths => %w{layouts snippets stylesheets javascripts assets admin system api},
:reserved_slugs => %w{stylesheets javascripts assets admin images api pages edit}, :reserved_slugs => %w{stylesheets javascripts assets admin images api pages edit},
:locales => %w{en de fr pt-BR it nl es}, :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', :cookie_key => '_locomotive_session',
:enable_logs => false, :enable_logs => false,
:hosting => :auto, :hosting => :auto,

View File

@ -5,6 +5,7 @@ require 'json/pure'
require 'devise' require 'devise'
require 'mongoid' require 'mongoid'
require 'mongoid_acts_as_tree' require 'mongoid_acts_as_tree'
require 'mongoid/i18n'
require 'will_paginate' require 'will_paginate'
require 'haml' require 'haml'
require 'liquid' require 'liquid'

92
lib/locomotive/i18n.rb Normal file
View 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

View File

@ -33,6 +33,12 @@ module Locomotive
path.gsub!(/\.[a-zA-Z][a-zA-Z0-9]{2,}$/, '') # remove the page extension path.gsub!(/\.[a-zA-Z][a-zA-Z0-9]{2,}$/, '') # remove the page extension
path.gsub!(/^\//, '') # remove the leading slash 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? path = 'index' if path.blank?
if path != 'index' if path != 'index'
@ -67,7 +73,10 @@ module Locomotive
'params' => self.params, 'params' => self.params,
'url' => request.url, 'url' => request.url,
'now' => Time.now.utc, '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) assigns.merge!(Locomotive.config.context_assign_extensions)

View File

@ -22,6 +22,7 @@ Gem::Specification.new do |s|
s.add_dependency 'devise', '1.3.4' s.add_dependency 'devise', '1.3.4'
s.add_dependency 'devise_bushido_authenticatable', '1.0.0.alpha10' s.add_dependency 'devise_bushido_authenticatable', '1.0.0.alpha10'
s.add_dependency 'mongoid', '2.0.2' s.add_dependency 'mongoid', '2.0.2'
s.add_dependency 'mongoid_i18n'
s.add_dependency 'bson_ext', '~> 1.3.0' s.add_dependency 'bson_ext', '~> 1.3.0'
s.add_dependency 'locomotive_mongoid_acts_as_tree', '0.1.5.7' s.add_dependency 'locomotive_mongoid_acts_as_tree', '0.1.5.7'
s.add_dependency 'will_paginate', '~> 3.0.0' s.add_dependency 'will_paginate', '~> 3.0.0'

View File

@ -165,4 +165,11 @@ $(document).ready(function() {
.trigger('refresh'); .trigger('refresh');
$('.formtastic fieldset.inputs ol li:not(.item)').last().addClass('last'); $('.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);
});
}); });

View File

@ -70,5 +70,6 @@ $(document).ready(function() {
}); });
}).hide(); }).hide();
// locales
$('#locales').sortable({ items: 'span', handle: 'label', tolerance: 'pointer', appendTo: 'body' });
}); });

View File

@ -13,6 +13,27 @@ function makeSlug(val, sep) { // code largely inspired by http://www.thewebsitet
return val.toLowerCase(); 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() { (function() {
String.prototype.trim = function() { String.prototype.trim = function() {
return this.replace(/^\s+/g, '').replace(/\s+$/g, ''); return this.replace(/^\s+/g, '').replace(/\s+$/g, '');

View File

@ -508,7 +508,7 @@ form.formtastic fieldset ol li.has-many ul li.template span.actions button span
font-size: 0.8em; font-size: 0.8em;
} }
/* ___ my account ___ */ /* ___ language / locales ___ */
form.formtastic fieldset.language li.full span { form.formtastic fieldset.language li.full span {
display: inline-block; display: inline-block;
@ -535,6 +535,14 @@ form.formtastic fieldset.language li.full span input {
margin-right: 2px; 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 ___ */ /* ___ membership ___ */
form.formtastic fieldset.email li.full input { form.formtastic fieldset.email li.full input {

View File

@ -107,7 +107,8 @@
background: transparent url(/images/admin/menu/submenu/action-border.png) repeat-y left 0; } background: transparent url(/images/admin/menu/submenu/action-border.png) repeat-y left 0; }
#submenu > .action a { #submenu > .action a {
margin-top: 18px; margin-top: 18px;
display: inline-block; display: block;
float: left;
background: rgba(0, 0, 0, 0.4); background: rgba(0, 0, 0, 0.4);
border-radius: 16px; border-radius: 16px;
-moz-border-radius: 16px; -moz-border-radius: 16px;

View 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; }

View File

@ -112,7 +112,8 @@
a { a {
margin-top: 18px; margin-top: 18px;
display: inline-block; display: block;
float: left;
background: rgba(0, 0, 0, 0.4); background: rgba(0, 0, 0, 0.4);
@include full-rounded(16px); @include full-rounded(16px);
padding: 0px 10px 0 15px; padding: 0px 10px 0 15px;

View 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;
}
}
}
}
}