Add support for enum site settings that render as a dropdown; use a dropdown for default_locale

This commit is contained in:
Neil Lalonde 2013-06-11 11:39:55 -04:00
parent c27d5dc2bd
commit 5ff7e570ac
9 changed files with 131 additions and 13 deletions

View file

@ -78,7 +78,16 @@ Discourse.SiteSetting = Discourse.Model.extend({
}).then(function() { }).then(function() {
setting.set('originalValue', setting.get('value')); setting.set('originalValue', setting.get('value'));
}); });
} },
validValues: function() {
var vals;
vals = Em.A();
this.get("valid_values").each(function(v){
vals.addObject({ name: v, value: v });
});
return vals;
}.property('valid_values')
}); });
Discourse.SiteSetting.reopenClass({ Discourse.SiteSetting.reopenClass({

View file

@ -0,0 +1,19 @@
{{#with view.content}}
<div class='span4 offset1'>
<h3>{{unbound setting}}</h3>
</div>
<div class="span11">
{{combobox valueAttribute="value" content=validValues value=value}}
<div class='desc'>{{unbound description}}</div>
</div>
{{#if dirty}}
<div class='span3'>
<button class='btn ok' {{action save this}}><i class='icon-ok'></i></button>
<button class='btn cancel' {{action cancel this}}><i class='icon-remove'></i></button>
</div>
{{else}}
{{#if overridden}}
<button class='btn' href='#' {{action resetDefault this}}>{{i18n admin.site_settings.reset}}</button>
{{/if}}
{{/if}}
{{/with}}

View file

@ -12,7 +12,10 @@ Discourse.SiteSettingView = Discourse.View.extend({
templateName: function() { templateName: function() {
// If we're editing a boolean, return a different template // If we're editing a boolean, return a different template
if (this.get('content.type') === 'bool') return 'admin/templates/site_settings/setting_bool' if (this.get('content.type') === 'bool') return 'admin/templates/site_settings/setting_bool';
// If we're editing an enum field, show a dropdown
if (this.get('content.type') === 'enum' ) return 'admin/templates/site_settings/setting_enum';
// Default to string editor // Default to string editor
return 'admin/templates/site_settings/setting_string'; return 'admin/templates/site_settings/setting_string';

View file

@ -0,0 +1,21 @@
class LocaleSiteSetting
def self.valid_value?(val)
supported_locales.include?(val)
end
def self.all_values
supported_locales
end
private
@lock = Mutex.new
def self.supported_locales
@lock.synchronize do
@supported_locales ||= Dir.glob( File.join(Rails.root, 'config', 'locales', 'client.*.yml') ).map {|x| x.split('.')[-2]}
end
end
end

View file

@ -203,7 +203,7 @@ class SiteSetting < ActiveRecord::Base
setting(:title_fancy_entities, true) setting(:title_fancy_entities, true)
# The default locale for the site # The default locale for the site
setting(:default_locale, 'en') setting(:default_locale, 'en', enum: 'LocaleSiteSetting')
client_setting(:educate_until_posts, 2) client_setting(:educate_until_posts, 2)

View file

@ -3,7 +3,7 @@ require_dependency 'enum'
module SiteSettingExtension module SiteSettingExtension
def types def types
@types ||= Enum.new(:string, :time, :fixnum, :float, :bool, :null) @types ||= Enum.new(:string, :time, :fixnum, :float, :bool, :null, :enum)
end end
def mutex def mutex
@ -19,10 +19,15 @@ module SiteSettingExtension
@defaults ||= {} @defaults ||= {}
end end
def setting(name, default = nil) def enums
@enums ||= {}
end
def setting(name, default = nil, opts = {})
mutex.synchronize do mutex.synchronize do
self.defaults[name] = default self.defaults[name] = default
current_value = current.has_key?(name) ? current[name] : default current_value = current.has_key?(name) ? current[name] : default
enums[name] = opts[:enum] if opts[:enum]
setup_methods(name, current_value) setup_methods(name, current_value)
end end
end end
@ -56,11 +61,12 @@ module SiteSettingExtension
def all_settings def all_settings
@defaults.map do |s, v| @defaults.map do |s, v|
value = send(s) value = send(s)
type = types[get_data_type(s, value)]
{setting: s, {setting: s,
description: description(s), description: description(s),
default: v, default: v,
type: types[get_data_type(value)].to_s, type: type.to_s,
value: value.to_s} value: value.to_s}.merge( type == :enum ? {valid_values: enum_class(s).all_values} : {})
end end
end end
@ -154,7 +160,7 @@ module SiteSettingExtension
return unless table_exists? return unless table_exists?
setting = SiteSetting.where(name: name).first setting = SiteSetting.where(name: name).first
type = get_data_type(defaults[name]) type = get_data_type(name, defaults[name])
if type == types[:bool] && val != true && val != false if type == types[:bool] && val != true && val != false
val = (val == "t" || val == "true") ? 't' : 'f' val = (val == "t" || val == "true") ? 't' : 'f'
@ -165,7 +171,11 @@ module SiteSettingExtension
end end
if type == types[:null] && val != '' if type == types[:null] && val != ''
type = get_data_type(val) type = get_data_type(name, val)
end
if type == types[:enum]
raise Discourse::InvalidParameters.new(:value) unless enum_class(name).valid_value?(val)
end end
if setting if setting
@ -182,10 +192,12 @@ module SiteSettingExtension
protected protected
def get_data_type(val) def get_data_type(name,val)
return types[:null] if val.nil? return types[:null] if val.nil?
if String === val if enums[name]
types[:enum]
elsif String === val
types[:string] types[:string]
elsif Fixnum === val elsif Fixnum === val
types[:fixnum] types[:fixnum]
@ -200,7 +212,7 @@ module SiteSettingExtension
case type case type
when types[:fixnum] when types[:fixnum]
value.to_i value.to_i
when types[:string] when types[:string], types[:enum]
value value
when types[:bool] when types[:bool]
value == "t" value == "t"
@ -242,6 +254,10 @@ module SiteSettingExtension
super(method, *args, &block) super(method, *args, &block)
end end
def enum_class(name)
enums[name] = enums[name].constantize unless enums[name].is_a?(Class)
enums[name]
end
end end

View file

@ -26,7 +26,7 @@ describe Admin::SiteSettingsController do
context 'update' do context 'update' do
it 'requires a value parameter' do it 'requires a value parameter' do
lambda { xhr :put, :update, id: 'test_setting' }.should raise_error(ActionController::ParameterMissing) lambda { xhr :put, :update, id: 'test_setting' }.should raise_error(ActionController::ParameterMissing)
end end
it 'sets the value when the param is present' do it 'sets the value when the param is present' do

View file

@ -0,0 +1,21 @@
require 'spec_helper'
describe LocaleSiteSetting do
describe 'valid_value?' do
it 'returns true for a locale that we have translations for' do
expect(LocaleSiteSetting.valid_value?('en')).to eq(true)
end
it 'returns false for a locale that we do not have translations for' do
expect(LocaleSiteSetting.valid_value?('swedish-chef')).to eq(false)
end
end
describe 'all_values' do
it 'returns all the locales that we have translations for' do
expect(LocaleSiteSetting.all_values.sort).to eq(Dir.glob( File.join(Rails.root, 'config', 'locales', 'client.*.yml') ).map {|x| x.split('.')[-2]}.sort)
end
end
end

View file

@ -114,6 +114,35 @@ describe SiteSetting do
end end
end end
describe 'enum setting' do
before :all do
@enum_class = Class.new
SiteSetting.setting(:test_enum, 'en', enum: @enum_class)
SiteSetting.refresh!
end
it 'should have the correct default' do
expect(SiteSetting.test_enum).to eq('en')
end
context 'when overridden' do
after :each do
SiteSetting.remove_override!(:test_enum)
end
it 'stores valid values' do
@enum_class.expects(:valid_value?).with('fr').returns(true)
SiteSetting.test_enum = 'fr'
expect(SiteSetting.test_enum).to eq('fr')
end
it 'rejects invalid values' do
@enum_class.expects(:valid_value?).with('gg').returns(false)
expect { SiteSetting.test_enum = 'gg' }.to raise_error(Discourse::InvalidParameters)
end
end
end
describe 'call_discourse_hub?' do describe 'call_discourse_hub?' do
it 'should be true when enforce_global_nicknames is true and discourse_org_access_key is set' do it 'should be true when enforce_global_nicknames is true and discourse_org_access_key is set' do
SiteSetting.enforce_global_nicknames = true SiteSetting.enforce_global_nicknames = true