Class: TrustyCms::Config

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/trusty_cms/config.rb,
lib/trusty_cms/config/definition.rb

Defined Under Namespace

Classes: ConfigError, Definition

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#definitionObject (readonly)

Returns the definition associated with this config item. If none has been declared this will be an empty definition that does not restrict use.



273
274
275
# File 'app/models/trusty_cms/config.rb', line 273

def definition
  @definition
end

Class Method Details

.[](key) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'app/models/trusty_cms/config.rb', line 76

def [](key)
  if database_exists?
    if table_exists?
      unless TrustyCms::Config.cache_file_exists?
        TrustyCms::Config.ensure_cache_file
        TrustyCms::Config.initialize_cache
      end
      TrustyCms::Config.initialize_cache if TrustyCms::Config.stale_cache?
      config_cache = Rails.cache.read('TrustyCms::Config')
      config_cache ? config_cache[key] : nil
    end
  end
end

.[]=(key, value) ⇒ Object



90
91
92
93
94
95
96
97
# File 'app/models/trusty_cms/config.rb', line 90

def []=(key, value)
  if database_exists?
    if table_exists?
      setting = where(key: key).first_or_initialize
      setting.value = value
    end
  end
end

.cache_fileObject



137
138
139
# File 'app/models/trusty_cms/config.rb', line 137

def cache_file
  File.join(cache_path, 'trusty_config_cache.txt')
end

.cache_file_exists?Boolean

Returns:

  • (Boolean)


118
119
120
# File 'app/models/trusty_cms/config.rb', line 118

def cache_file_exists?
  File.file?(cache_file)
end

.cache_pathObject



133
134
135
# File 'app/models/trusty_cms/config.rb', line 133

def cache_path
  "#{Rails.root}/tmp"
end

.database_exists?Boolean

Returns:

  • (Boolean)


99
100
101
102
103
104
105
# File 'app/models/trusty_cms/config.rb', line 99

def database_exists?
  ActiveRecord::Base.connection
rescue ActiveRecord::NoDatabaseError
  false
else
  true
end

.default_settingsObject



145
146
147
# File 'app/models/trusty_cms/config.rb', line 145

def default_settings
  @default_settings ||= %w{defaults.locale defaults.page.filter defaults.page.parts defaults.page.fields defaults.page.status}
end

.define(key, options = {}) ⇒ Object

Declares a setting definition that will constrain and support the use of a particular config entry.

define('setting.key', options)

Can take several options:

  • :default is the value that will be placed in the database if none has been set already

  • :type can be :string, :boolean or :integer. Note that all settings whose key ends in ? are considered boolean.

  • :select_from should be a list or hash suitable for passing to options_for_select, or a block that will return such a list at runtime

  • :validate_with should be a block that will receive a value and return true or false. Validations are also implied by type or select_from.

  • :allow_blank should be false if the config item must not be blank or nil

  • :allow_change should be false if the config item can only be set, not changed. Add a default to specify an unchanging config entry.

  • :allow_display should be false if the config item should not be showable in radius tags

    TrustyCms.config do |config|

    config.define 'defaults.locale', :select_from => lambda { TrustyCms::AvailableLocales.locales }, :allow_blank => true
    config.define 'defaults.page.parts', :default => "Body,Extended"
    ...
    

    end

It’s also possible to reuse a definition by passing it to define:

choose_layout = TrustyCms::Config::Definition.new(:select_from => lambda {Layout.all.map{|l| [l.name, l.d]}})
define "my.layout", choose_layout
define "your.layout", choose_layout

but at the moment that’s only done in testing.



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'app/models/trusty_cms/config.rb', line 195

def define(key, options = {})
  called_from = caller.grep(/\/initializers\//).first
  if options.is_a? TrustyCms::Config::Definition
    definition = options
  else
    key = [options[:prefix], key].join('.') if options[:prefix]
  end

  definition ||= TrustyCms::Config::Definition.new(options.merge(definer: called_from))
  definitions[key] = definition

  if self[key].nil? && !definition.default.nil?
    begin
      self[key] = definition.default
    rescue ActiveRecord::RecordInvalid
      raise LoadError, "Default configuration invalid: value '#{definition.default}' is not allowed for '#{key}'"
    end
  end
end

.definition_for(key) ⇒ Object



219
220
221
# File 'app/models/trusty_cms/config.rb', line 219

def definition_for(key)
  definitions[key] ||= TrustyCms::Config::Definition.new(empty: true)
end

.definitionsObject



215
216
217
# File 'app/models/trusty_cms/config.rb', line 215

def definitions
  TrustyCms.config_definitions
end

.ensure_cache_fileObject



128
129
130
131
# File 'app/models/trusty_cms/config.rb', line 128

def ensure_cache_file
  FileUtils.mkpath(cache_path)
  FileUtils.touch(cache_file)
end

.initialize_cacheObject



111
112
113
114
115
116
# File 'app/models/trusty_cms/config.rb', line 111

def initialize_cache
  TrustyCms::Config.ensure_cache_file
  Rails.cache.write('TrustyCms::Config', TrustyCms::Config.to_hash)
  Rails.cache.write('TrustyCms.cache_mtime', File.mtime(cache_file))
  Rails.cache.silence!
end

.namespace(prefix, options = {}, &block) ⇒ Object

A convenient drying method for specifying a prefix and options common to several settings.

TrustyCms.config do |config|
  config.namespace('secret', :allow_display => false) do |secret|
    secret.define('identity', :default => 'batman')      # defines 'secret.identity'
    secret.define('lair', :default => 'batcave')         # defines 'secret.lair'
    secret.define('longing', :default => 'vindication')  # defines 'secret.longing'
  end
end


163
164
165
166
# File 'app/models/trusty_cms/config.rb', line 163

def namespace(prefix, options = {}, &block)
  prefix = [options[:prefix], prefix].join('.') if options[:prefix]
  with_options(options.merge(prefix: prefix), &block)
end

.site_settingsObject



141
142
143
# File 'app/models/trusty_cms/config.rb', line 141

def site_settings
  @site_settings ||= %w{site.title site.host dev.host local.timezone}
end

.stale_cache?Boolean

Returns:

  • (Boolean)


122
123
124
125
126
# File 'app/models/trusty_cms/config.rb', line 122

def stale_cache?
  return true unless TrustyCms::Config.cache_file_exists?

  Rails.cache.read('TrustyCms.cache_mtime') != File.mtime(cache_file)
end

.to_hashObject



107
108
109
# File 'app/models/trusty_cms/config.rb', line 107

def to_hash
  Hash[*all.map { |pair| [pair.key, pair.value] }.flatten]
end

.user_settingsObject



149
150
151
# File 'app/models/trusty_cms/config.rb', line 149

def 
  @user_settings ||= ['user.allow_password_reset?']
end

Instance Method Details

#boolean?Boolean

Returns true if the item key ends with ‘?’ or the definition specifies :type => :boolean.

Returns:

  • (Boolean)


279
280
281
# File 'app/models/trusty_cms/config.rb', line 279

def boolean?
  definition.boolean? || key.ends_with?('?')
end

#checked?Boolean

Returns true if the item is boolean and true.

Returns:

  • (Boolean)


285
286
287
288
289
# File 'app/models/trusty_cms/config.rb', line 285

def checked?
  return nil if self[:value].nil?

  boolean? && self[:value] == 'true'
end

#selected_valueObject

Returns a name corresponding to the current setting value, if the setting definition includes a select_from parameter.



299
300
301
# File 'app/models/trusty_cms/config.rb', line 299

def selected_value
  definition.selected(value)
end

#selector?Boolean

Returns true if the item defintion includes a :select_from parameter that limits the range of permissible options.

Returns:

  • (Boolean)


293
294
295
# File 'app/models/trusty_cms/config.rb', line 293

def selector?
  definition.selector?
end

#update_cacheObject



303
304
305
# File 'app/models/trusty_cms/config.rb', line 303

def update_cache
  TrustyCms::Config.initialize_cache
end

#validateObject



309
310
311
# File 'app/models/trusty_cms/config.rb', line 309

def validate
  definition.validate(self)
end

#valueObject

Requesting a config item:

key = TrustyCms.config['key']

is equivalent to this:

key = TrustyCms::Config.find_or_create_by_key('key').value

If the config item is boolean the response will be true or false. For items with :type => :integer it will be an integer, for everything else a string.



262
263
264
265
266
267
268
# File 'app/models/trusty_cms/config.rb', line 262

def value
  if boolean?
    checked?
  else
    self[:value]
  end
end

#value=(param) ⇒ Object

The usual way to use a config item:

TrustyCms.config['key'] = value

is equivalent to this:

TrustyCms::Config.find_or_create_by_key('key').value = value

Calling value= also applies any validations and restrictions that are found in the associated definition. so this will raise a ConfigError if you try to change a protected config entry or a RecordInvalid if you set a value that is not among those permitted.



236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'app/models/trusty_cms/config.rb', line 236

def value=(param)
  newvalue = param.to_s
  if newvalue != self[:value]
    raise ConfigError, "#{key} cannot be changed" unless settable? || self[:value].blank?

    self[:value] = if boolean?
                     newvalue == '1' || newvalue == 'true' ? 'true' : 'false'
                   else
                     newvalue
                   end
    save!
  end
  self[:value]
end