radiant-settings-extension 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/HELP_admin.md +16 -0
- data/README.markdown +24 -0
- data/Rakefile +136 -0
- data/VERSION +1 -0
- data/app/controllers/admin/settings_controller.rb +40 -0
- data/app/helpers/admin/settings_helper.rb +11 -0
- data/app/views/admin/settings/_setting.html.haml +27 -0
- data/app/views/admin/settings/edit.html.haml +40 -0
- data/app/views/admin/settings/index.html.haml +42 -0
- data/app/views/admin/settings/new.html.haml +45 -0
- data/config/locales/en.yml +3 -0
- data/config/routes.rb +5 -0
- data/cucumber.yml +1 -0
- data/db/migrate/001_add_description_to_config.rb +53 -0
- data/db/migrate/002_add_settings_roles.rb +13 -0
- data/features/support/env.rb +16 -0
- data/features/support/paths.rb +14 -0
- data/lib/config_find_all_as_tree.rb +35 -0
- data/lib/config_protection.rb +13 -0
- data/lib/settings_tags.rb +22 -0
- data/lib/tasks/settings_extension_tasks.rake +55 -0
- data/public/images/.DS_Store +0 -0
- data/public/images/admin/.DS_Store +0 -0
- data/public/images/admin/setting.png +0 -0
- data/settings_extension.rb +38 -0
- data/spec/controllers/admin/settings_controller_spec.rb +78 -0
- data/spec/helpers/admin/settings_helper_spec.rb +9 -0
- data/spec/lib/radiant/admin_ui_spec.rb +20 -0
- data/spec/lib/settings_tags_spec.rb +16 -0
- data/spec/models/config_spec.rb +18 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/views/admin/settings/edit_view_spec.rb +30 -0
- data/spec/views/admin/settings/index_view_spec.rb +62 -0
- metadata +109 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.svn
|
data/HELP_admin.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
If you would like to make the settings tab invisible to certain users,
|
2
|
+
You may edit the `roles.settings` value.
|
3
|
+
|
4
|
+
You have several options to display the tab, but keep in mind that deleting
|
5
|
+
this setting or saving it as an empty value will allow **all** users to see
|
6
|
+
the "Settings" tab.
|
7
|
+
|
8
|
+
Here are the possible values that you may use:
|
9
|
+
|
10
|
+
1. `admin` (for admin only)
|
11
|
+
2. `developer` (for developers only)
|
12
|
+
3. `admin, developer` (for both developers and admin users)
|
13
|
+
4. `all` (for everyone)
|
14
|
+
|
15
|
+
After making these changes, you'll need to restart the application to see
|
16
|
+
the access changed in production.
|
data/README.markdown
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Radiant Settings Extension
|
2
|
+
==========================
|
3
|
+
|
4
|
+
A simple configuration editor for Radiant. It adds a simple "Settings" tab that allows manage the configuration settings.
|
5
|
+
|
6
|
+
After installation be sure to update your instance of radiant!
|
7
|
+
|
8
|
+
rake radiant:extensions:settings:update
|
9
|
+
rake radiant:extensions:settings:migrate
|
10
|
+
|
11
|
+
Extension Developers
|
12
|
+
--------------------
|
13
|
+
|
14
|
+
If you are using Radiant::Config to store settings for your extensions, then you can add some textile formatted text into
|
15
|
+
the "description" attribute the Radiant::Config model. This prose will show up on the the edit setting page making it
|
16
|
+
more clear just what that setting does.
|
17
|
+
|
18
|
+
|
19
|
+
Radius-Tags
|
20
|
+
-----------
|
21
|
+
|
22
|
+
Radiant Settings Extension allows you to access Radiant::Config via <r:config:settings key="key" />.
|
23
|
+
|
24
|
+
Use <r:config:setting key="admin.title" /> for Radiant::Config['admin.title'].
|
data/Rakefile
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gem|
|
4
|
+
gem.name = "radiant-settings-extension"
|
5
|
+
gem.summary = %Q{Settings Extension for Radiant CMS}
|
6
|
+
gem.description = %Q{Allows users to edit the details of the config table.}
|
7
|
+
gem.email = "jim@saturnflyer.com"
|
8
|
+
gem.homepage = "http://github.com/saturnflyer/radiant-settings-extension"
|
9
|
+
gem.authors = ['Alex Wayne','Jim Gay']
|
10
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
11
|
+
end
|
12
|
+
rescue LoadError
|
13
|
+
puts "Jeweler (or a dependency) not available. This is only required if you plan to package settings as a gem."
|
14
|
+
end
|
15
|
+
|
16
|
+
# In rails 1.2, plugins aren't available in the path until they're loaded.
|
17
|
+
# Check to see if the rspec plugin is installed first and require
|
18
|
+
# it if it is. If not, use the gem version.
|
19
|
+
|
20
|
+
# Determine where the RSpec plugin is by loading the boot
|
21
|
+
unless defined? RADIANT_ROOT
|
22
|
+
ENV["RAILS_ENV"] = "test"
|
23
|
+
case
|
24
|
+
when ENV["RADIANT_ENV_FILE"]
|
25
|
+
require File.dirname(ENV["RADIANT_ENV_FILE"]) + "/boot"
|
26
|
+
when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
|
27
|
+
require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot"
|
28
|
+
else
|
29
|
+
require "#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
require 'rake'
|
34
|
+
require 'rake/rdoctask'
|
35
|
+
require 'rake/testtask'
|
36
|
+
|
37
|
+
rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
|
38
|
+
$LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
|
39
|
+
require 'spec/rake/spectask'
|
40
|
+
require 'cucumber'
|
41
|
+
require 'cucumber/rake/task'
|
42
|
+
|
43
|
+
# Cleanup the RADIANT_ROOT constant so specs will load the environment
|
44
|
+
Object.send(:remove_const, :RADIANT_ROOT)
|
45
|
+
|
46
|
+
extension_root = File.expand_path(File.dirname(__FILE__))
|
47
|
+
|
48
|
+
task :default => :spec
|
49
|
+
task :stats => "spec:statsetup"
|
50
|
+
|
51
|
+
desc "Run all specs in spec directory"
|
52
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
53
|
+
t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
|
54
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
55
|
+
end
|
56
|
+
|
57
|
+
task :features => 'spec:integration'
|
58
|
+
|
59
|
+
namespace :spec do
|
60
|
+
desc "Run all specs in spec directory with RCov"
|
61
|
+
Spec::Rake::SpecTask.new(:rcov) do |t|
|
62
|
+
t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
|
63
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
64
|
+
t.rcov = true
|
65
|
+
t.rcov_opts = ['--exclude', 'spec', '--rails']
|
66
|
+
end
|
67
|
+
|
68
|
+
desc "Print Specdoc for all specs"
|
69
|
+
Spec::Rake::SpecTask.new(:doc) do |t|
|
70
|
+
t.spec_opts = ["--format", "specdoc", "--dry-run"]
|
71
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
72
|
+
end
|
73
|
+
|
74
|
+
[:models, :controllers, :views, :helpers].each do |sub|
|
75
|
+
desc "Run the specs under spec/#{sub}"
|
76
|
+
Spec::Rake::SpecTask.new(sub) do |t|
|
77
|
+
t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
|
78
|
+
t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
desc "Run the Cucumber features"
|
83
|
+
Cucumber::Rake::Task.new(:integration) do |t|
|
84
|
+
t.fork = true
|
85
|
+
t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'pretty')]
|
86
|
+
# t.feature_pattern = "#{extension_root}/features/**/*.feature"
|
87
|
+
t.profile = "default"
|
88
|
+
end
|
89
|
+
|
90
|
+
# Setup specs for stats
|
91
|
+
task :statsetup do
|
92
|
+
require 'code_statistics'
|
93
|
+
::STATS_DIRECTORIES << %w(Model\ specs spec/models)
|
94
|
+
::STATS_DIRECTORIES << %w(View\ specs spec/views)
|
95
|
+
::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers)
|
96
|
+
::STATS_DIRECTORIES << %w(Helper\ specs spec/views)
|
97
|
+
::CodeStatistics::TEST_TYPES << "Model specs"
|
98
|
+
::CodeStatistics::TEST_TYPES << "View specs"
|
99
|
+
::CodeStatistics::TEST_TYPES << "Controller specs"
|
100
|
+
::CodeStatistics::TEST_TYPES << "Helper specs"
|
101
|
+
::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
|
102
|
+
end
|
103
|
+
|
104
|
+
namespace :db do
|
105
|
+
namespace :fixtures do
|
106
|
+
desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y"
|
107
|
+
task :load => :environment do
|
108
|
+
require 'active_record/fixtures'
|
109
|
+
ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
|
110
|
+
(ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
|
111
|
+
Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
desc 'Generate documentation for the settings extension.'
|
119
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
120
|
+
rdoc.rdoc_dir = 'rdoc'
|
121
|
+
rdoc.title = 'SettingsExtension'
|
122
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
123
|
+
rdoc.rdoc_files.include('README')
|
124
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
125
|
+
end
|
126
|
+
|
127
|
+
# For extensions that are in transition
|
128
|
+
desc 'Test the settings extension.'
|
129
|
+
Rake::TestTask.new(:test) do |t|
|
130
|
+
t.libs << 'lib'
|
131
|
+
t.pattern = 'test/**/*_test.rb'
|
132
|
+
t.verbose = true
|
133
|
+
end
|
134
|
+
|
135
|
+
# Load any custom rakefiles for extension
|
136
|
+
Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.1.1
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class Admin::SettingsController < ApplicationController
|
2
|
+
|
3
|
+
only_allow_access_to :new, :create, :destroy,
|
4
|
+
:when => (Radiant::Config['roles.settings'].split(',').collect{|s| s.strip.underscore }.map(&:to_sym) || :admin),
|
5
|
+
:denied_url => {:action => 'index'},
|
6
|
+
:denied_message => "See your administrator if you'd like to create a new setting or delete an existing one."
|
7
|
+
|
8
|
+
def index
|
9
|
+
@settings = Radiant::Config.find_all_as_tree
|
10
|
+
end
|
11
|
+
|
12
|
+
def new
|
13
|
+
@setting = Radiant::Config.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def create
|
17
|
+
@setting = Radiant::Config.find_or_create_by_key(params[:setting]['key'])
|
18
|
+
@setting.update_attributes(params[:setting])
|
19
|
+
flash[:notice] = "The setting \"#{@setting.key}\" was created."
|
20
|
+
redirect_to admin_settings_url
|
21
|
+
end
|
22
|
+
|
23
|
+
def edit
|
24
|
+
@setting = Radiant::Config.find(params[:id])
|
25
|
+
end
|
26
|
+
|
27
|
+
def update
|
28
|
+
Radiant::Config.find(params[:id]).update_attribute(:value, params[:setting][:value])
|
29
|
+
redirect_to admin_settings_url
|
30
|
+
end
|
31
|
+
|
32
|
+
def destroy
|
33
|
+
@setting = Radiant::Config.find(params[:id])
|
34
|
+
@key = @setting.key
|
35
|
+
@setting.destroy
|
36
|
+
flash[:notice] = "The setting \"#{@key}\" was deleted."
|
37
|
+
redirect_to admin_settings_url
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Admin::SettingsHelper
|
2
|
+
def render_node(key, object, options = {})
|
3
|
+
@depth ||= 0
|
4
|
+
|
5
|
+
if object.is_a?(Radiant::Config)
|
6
|
+
render :partial => 'setting', :locals => { :key => key, :setting => object, :hash => nil }
|
7
|
+
else
|
8
|
+
render :partial => 'setting', :locals => { :key => key, :setting => nil, :hash => object }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
%tr.node
|
2
|
+
%td.layout
|
3
|
+
- @depth.times do
|
4
|
+
.nest-padding
|
5
|
+
|
6
|
+
- if setting
|
7
|
+
%span.title= link_to "#{image_tag('admin/setting.png', :size => '16x16')} #{key.humanize}", edit_admin_setting_path(setting), :title => setting.key
|
8
|
+
|
9
|
+
- else
|
10
|
+
%span.title.label= key.humanize
|
11
|
+
|
12
|
+
|
13
|
+
%td
|
14
|
+
- if setting
|
15
|
+
= setting.protected_value
|
16
|
+
|
17
|
+
- if hash
|
18
|
+
- @depth += 1
|
19
|
+
|
20
|
+
- hash.each do |key, value|
|
21
|
+
= render_node key, value
|
22
|
+
|
23
|
+
- @depth -= 1
|
24
|
+
|
25
|
+
- if @depth == 0
|
26
|
+
%tr.spacer
|
27
|
+
%td{ :colspan => 2 }
|
@@ -0,0 +1,40 @@
|
|
1
|
+
- body_classes << 'reversed'
|
2
|
+
- content_for 'page_css' do
|
3
|
+
:sass
|
4
|
+
h2.setting-name
|
5
|
+
color: #C00
|
6
|
+
font-size: 200%
|
7
|
+
font-family: Georgia,Palatino,"Times New Roman",Times,serif
|
8
|
+
font-weight: normal
|
9
|
+
margin: 25px 0 0
|
10
|
+
|
11
|
+
div.description
|
12
|
+
margin: 5px 20px
|
13
|
+
color: #444
|
14
|
+
|
15
|
+
p
|
16
|
+
margin: 0 0 10px
|
17
|
+
|
18
|
+
%h1= @setting.key
|
19
|
+
|
20
|
+
- form_for :setting, :url => admin_setting_path(@setting), :html => { :method => :put } do |f|
|
21
|
+
.form-area
|
22
|
+
%p.title
|
23
|
+
%label
|
24
|
+
Setting Value
|
25
|
+
- if @setting.protected?
|
26
|
+
= f.password_field :value, :class => 'textbox'
|
27
|
+
- else
|
28
|
+
= f.text_field :value, :class => 'textbox'
|
29
|
+
.description= textilize @setting.description
|
30
|
+
|
31
|
+
%p.buttons
|
32
|
+
= save_model_button(@setting)
|
33
|
+
= save_model_and_continue_editing_button(@setting)
|
34
|
+
or
|
35
|
+
= link_to 'Cancel', admin_settings_url
|
36
|
+
|
37
|
+
%p.buttons
|
38
|
+
- if admin?
|
39
|
+
This system relies on some of these settings to work properly. Deleting settings may cause unexpected errors.
|
40
|
+
= link_to "I understand. Delete this setting entirely.", admin_setting_path(@setting), :method => :delete if admin?
|
@@ -0,0 +1,42 @@
|
|
1
|
+
- content_for 'page_css' do
|
2
|
+
:sass
|
3
|
+
table#settings_index
|
4
|
+
span.label
|
5
|
+
color: #666
|
6
|
+
font-size: 1.2em
|
7
|
+
|
8
|
+
div.nest-padding
|
9
|
+
width: 35px
|
10
|
+
height: 10px
|
11
|
+
float: left
|
12
|
+
|
13
|
+
tr.spacer
|
14
|
+
td
|
15
|
+
background: #EAEAEA
|
16
|
+
height: 3px
|
17
|
+
padding: 0
|
18
|
+
p.new
|
19
|
+
a
|
20
|
+
color: #000
|
21
|
+
border: 1px solid #ddf
|
22
|
+
padding: 6px
|
23
|
+
text-decoration: none
|
24
|
+
&:hover
|
25
|
+
background: #efefff
|
26
|
+
.outset
|
27
|
+
- render_region :top
|
28
|
+
- render_region :main do |main|
|
29
|
+
- main.list do
|
30
|
+
%table#settings_index.index
|
31
|
+
%thead
|
32
|
+
%tr
|
33
|
+
%th.key Radiant::Config Key
|
34
|
+
%th.value Value
|
35
|
+
%tbody
|
36
|
+
- @settings.each do |key, node|
|
37
|
+
= render_node key, node, :reset_depth => true
|
38
|
+
#actions
|
39
|
+
- render_region :bottom do |bottom|
|
40
|
+
- bottom.new_button do
|
41
|
+
%ul
|
42
|
+
%li.new= link_to "New Setting", new_admin_setting_url if admin?
|
@@ -0,0 +1,45 @@
|
|
1
|
+
- body_classes << 'reversed'
|
2
|
+
- content_for 'page_css' do
|
3
|
+
:sass
|
4
|
+
h2.setting-name
|
5
|
+
color: #C00
|
6
|
+
font-size: 200%
|
7
|
+
font-family: Georgia,Palatino,"Times New Roman",Times,serif
|
8
|
+
font-weight: normal
|
9
|
+
margin: 25px 0 0
|
10
|
+
|
11
|
+
div.description
|
12
|
+
margin: 5px 20px
|
13
|
+
color: #444
|
14
|
+
|
15
|
+
p.title
|
16
|
+
margin: 10px 0 !important
|
17
|
+
|
18
|
+
textarea.textarea
|
19
|
+
height: 150px !important
|
20
|
+
width: 100%
|
21
|
+
display: block
|
22
|
+
|
23
|
+
%h1
|
24
|
+
New Radiant Setting
|
25
|
+
|
26
|
+
- form_for :setting, :url => admin_settings_path do |f|
|
27
|
+
.form-area
|
28
|
+
%p.title
|
29
|
+
%label
|
30
|
+
Setting Name
|
31
|
+
= f.text_field :key, :class => 'textbox'
|
32
|
+
%p.title
|
33
|
+
%label
|
34
|
+
Setting Value
|
35
|
+
= f.text_field :value, :class => 'textbox'
|
36
|
+
%p.title
|
37
|
+
%label
|
38
|
+
Setting Description
|
39
|
+
= f.text_area :description, :class => 'textarea'
|
40
|
+
|
41
|
+
%p.buttons
|
42
|
+
= save_model_button(@setting, :label => 'Create Setting')
|
43
|
+
= save_model_and_continue_editing_button(@setting)
|
44
|
+
or
|
45
|
+
= link_to 'Cancel', admin_settings_url
|
data/config/routes.rb
ADDED
data/cucumber.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
default: --format progress features --tags ~@proposed,~@in_progress
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class AddDescriptionToConfig < ActiveRecord::Migration
|
2
|
+
|
3
|
+
class Config < ActiveRecord::Base; end
|
4
|
+
|
5
|
+
def self.up
|
6
|
+
add_column :config, :description, :text
|
7
|
+
|
8
|
+
puts "-- Adding description for base radiant settings"
|
9
|
+
|
10
|
+
|
11
|
+
Config.find(:all).each do |c|
|
12
|
+
description = case c.key
|
13
|
+
when 'admin.title'
|
14
|
+
'Title text displayed at the top of all administration screens.'
|
15
|
+
|
16
|
+
when 'admin.subtitle'
|
17
|
+
'The tagline displayed underneath the main administration title'
|
18
|
+
|
19
|
+
when 'defaults.page.parts'
|
20
|
+
<<-DESC
|
21
|
+
Defines the page parts that a new page is created with. It should be a list, separated by a comma and a space. For example:
|
22
|
+
|
23
|
+
bq. @body, extended, sidebar@
|
24
|
+
DESC
|
25
|
+
|
26
|
+
when 'defaults.page.status'
|
27
|
+
<<-DESC
|
28
|
+
Defines the publishing status of new pages. This can any one of:
|
29
|
+
|
30
|
+
* draft
|
31
|
+
* published
|
32
|
+
* reviewed
|
33
|
+
* hidden
|
34
|
+
DESC
|
35
|
+
when 'defaults.page.filter'
|
36
|
+
<<-DESC
|
37
|
+
Sets the text filter a new page has by default. Valid options, in a vanilla Radiant install are:
|
38
|
+
|
39
|
+
* _leave blank to set no default filter_
|
40
|
+
* Markdown
|
41
|
+
* SmartyPants
|
42
|
+
* Textile
|
43
|
+
DESC
|
44
|
+
end
|
45
|
+
|
46
|
+
c.update_attribute :description, description
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.down
|
51
|
+
remove_column :config, :description
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class AddSettingsRoles < ActiveRecord::Migration
|
2
|
+
|
3
|
+
class Config < ActiveRecord::Base; end
|
4
|
+
|
5
|
+
def self.up
|
6
|
+
Config.create!(:key => 'roles.settings', :value => 'admin', :description => 'List of user roles that may see the settings tabs.')
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.down
|
10
|
+
# Not really necessary
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Sets up the Rails environment for Cucumber
|
2
|
+
ENV["RAILS_ENV"] = "test"
|
3
|
+
# Extension root
|
4
|
+
extension_env = File.expand_path(File.dirname(__FILE__) + '/../../../../../config/environment')
|
5
|
+
require extension_env+'.rb'
|
6
|
+
|
7
|
+
Dir.glob(File.join(RADIANT_ROOT, "features", "**", "*.rb")).each {|step| require step}
|
8
|
+
|
9
|
+
Cucumber::Rails::World.class_eval do
|
10
|
+
include Dataset
|
11
|
+
datasets_directory "#{RADIANT_ROOT}/spec/datasets"
|
12
|
+
Dataset::Resolver.default = Dataset::DirectoryResolver.new("#{RADIANT_ROOT}/spec/datasets", File.dirname(__FILE__) + '/../../spec/datasets', File.dirname(__FILE__) + '/../datasets')
|
13
|
+
self.datasets_database_dump_path = "#{Rails.root}/tmp/dataset"
|
14
|
+
|
15
|
+
# dataset :settings
|
16
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module ConfigFindAllAsTree
|
2
|
+
|
3
|
+
def find_all_as_tree
|
4
|
+
returning(ActiveSupport::OrderedHash.new) do |result|
|
5
|
+
|
6
|
+
db_key = (ActiveRecord::Base.connection.adapter_name.downcase == 'mysql' ? '`key`' : 'key')
|
7
|
+
|
8
|
+
# For all settings
|
9
|
+
find(:all, :order => db_key).each do |setting|
|
10
|
+
|
11
|
+
# Split the setting path into an array
|
12
|
+
path = setting.key.split('.')
|
13
|
+
|
14
|
+
# Set the current level to the root of the hash
|
15
|
+
current_level = result
|
16
|
+
|
17
|
+
# iterate through all path levels
|
18
|
+
path.each do |path_element|
|
19
|
+
if path_element.equal?(path.last)
|
20
|
+
# We are at the end of the path, so set the settting object as the value
|
21
|
+
current_level[path_element] = setting
|
22
|
+
|
23
|
+
else
|
24
|
+
# Not at the end yet, so first make sure that there is a hash for this key
|
25
|
+
current_level[path_element] ||= ActiveSupport::OrderedHash.new
|
26
|
+
|
27
|
+
# Reset the curent level to this hash object for this key
|
28
|
+
current_level = current_level[path_element]
|
29
|
+
end
|
30
|
+
end # if
|
31
|
+
end # each
|
32
|
+
end # returning
|
33
|
+
end # find_all_as_tree
|
34
|
+
|
35
|
+
end # ConfigFindAllAsTree
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module SettingsTags
|
2
|
+
include Radiant::Taggable
|
3
|
+
|
4
|
+
class TagError < StandardError; end
|
5
|
+
|
6
|
+
tag "config" do |tag|
|
7
|
+
tag.expand
|
8
|
+
end
|
9
|
+
|
10
|
+
desc %{
|
11
|
+
Renders the Radiant::Config setting specified by the required 'key' attribute.
|
12
|
+
|
13
|
+
*Usage*:
|
14
|
+
|
15
|
+
<pre><code><r:config:setting key="admin.title" /></code></pre>
|
16
|
+
}
|
17
|
+
tag "config:setting" do |tag|
|
18
|
+
raise TagError, "'key' attribute required" unless key = tag.attr['key']
|
19
|
+
Radiant::Config["#{key}"]
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
namespace :radiant do
|
2
|
+
namespace :extensions do
|
3
|
+
namespace :settings do
|
4
|
+
|
5
|
+
desc "Runs the migration of the Settings extension"
|
6
|
+
task :migrate => :environment do
|
7
|
+
require 'radiant/extension_migrator'
|
8
|
+
if ENV["VERSION"]
|
9
|
+
SettingsExtension.migrator.migrate(ENV["VERSION"].to_i)
|
10
|
+
Rake::Task['db:schema:dump'].invoke
|
11
|
+
else
|
12
|
+
SettingsExtension.migrator.migrate
|
13
|
+
Rake::Task['db:schema:dump'].invoke
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Copies public assets of the Settings to the instance public/ directory."
|
18
|
+
task :update => :environment do
|
19
|
+
is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
|
20
|
+
puts "Copying assets from SettingsExtension"
|
21
|
+
Dir[SettingsExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
|
22
|
+
path = file.sub(SettingsExtension.root, '')
|
23
|
+
directory = File.dirname(path)
|
24
|
+
mkdir_p RAILS_ROOT + directory, :verbose => false
|
25
|
+
cp file, RAILS_ROOT + path, :verbose => false
|
26
|
+
end
|
27
|
+
unless SettingsExtension.root.starts_with? RAILS_ROOT # don't need to copy vendored tasks
|
28
|
+
puts "Copying rake tasks from SettingsExtension"
|
29
|
+
local_tasks_path = File.join(RAILS_ROOT, %w(lib tasks))
|
30
|
+
mkdir_p local_tasks_path, :verbose => false
|
31
|
+
Dir[File.join SettingsExtension.root, %w(lib tasks *.rake)].each do |file|
|
32
|
+
cp file, local_tasks_path, :verbose => false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "Syncs all available translations for this ext to the English ext master"
|
38
|
+
task :sync => :environment do
|
39
|
+
# The main translation root, basically where English is kept
|
40
|
+
language_root = SettingsExtension.root + "/config/locales"
|
41
|
+
words = TranslationSupport.get_translation_keys(language_root)
|
42
|
+
|
43
|
+
Dir["#{language_root}/*.yml"].each do |filename|
|
44
|
+
next if filename.match('_available_tags')
|
45
|
+
basename = File.basename(filename, '.yml')
|
46
|
+
puts "Syncing #{basename}"
|
47
|
+
(comments, other) = TranslationSupport.read_file(filename, basename)
|
48
|
+
words.each { |k,v| other[k] ||= words[k] } # Initializing hash variable as empty if it does not exist
|
49
|
+
other.delete_if { |k,v| !words[k] } # Remove if not defined in en.yml
|
50
|
+
TranslationSupport.write_file(filename, basename, comments, other)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Uncomment this if you reference any of your controllers in activate
|
2
|
+
# require_dependency 'application_controller'
|
3
|
+
|
4
|
+
class SettingsExtension < Radiant::Extension
|
5
|
+
version "#{File.read(File.expand_path(File.dirname(__FILE__)) + '/VERSION')}"
|
6
|
+
description "Web based administration for Radiant default configuration settings."
|
7
|
+
url "http://github.com/Squeegy/radiant-settings"
|
8
|
+
|
9
|
+
def activate
|
10
|
+
Radiant::Config.extend ConfigFindAllAsTree
|
11
|
+
Radiant::Config.class_eval { include ConfigProtection }
|
12
|
+
|
13
|
+
tab 'Settings' do
|
14
|
+
add_item 'Application', '/admin/settings', :after => 'Extensions'
|
15
|
+
end
|
16
|
+
|
17
|
+
Page.class_eval { include SettingsTags }
|
18
|
+
|
19
|
+
Radiant::AdminUI.class_eval do
|
20
|
+
attr_accessor :settings
|
21
|
+
end
|
22
|
+
admin.settings = load_default_settings_regions
|
23
|
+
end
|
24
|
+
|
25
|
+
def deactivate
|
26
|
+
end
|
27
|
+
|
28
|
+
def load_default_settings_regions
|
29
|
+
returning OpenStruct.new do |settings|
|
30
|
+
settings.index = Radiant::AdminUI::RegionSet.new do |index|
|
31
|
+
index.top.concat %w{}
|
32
|
+
index.main.concat %w{list}
|
33
|
+
index.bottom.concat %w{new_button}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe Admin::SettingsController do
|
4
|
+
dataset :users
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@parts = mock_model(Radiant::Config)
|
8
|
+
@parts.stub!(:key).and_return('defaults.page.parts')
|
9
|
+
@parts.stub!(:value).and_return('body, extended')
|
10
|
+
|
11
|
+
@title = mock_model(Radiant::Config)
|
12
|
+
@title.stub!(:key).and_return('admin.title')
|
13
|
+
@title.stub!(:value).and_return('Radiant CMS')
|
14
|
+
|
15
|
+
login_as :existing
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'GET /admin/settings' do
|
19
|
+
before do
|
20
|
+
@tree = {
|
21
|
+
'admin' => {
|
22
|
+
'title' => @title
|
23
|
+
},
|
24
|
+
'defaults' => {
|
25
|
+
'page' => {
|
26
|
+
'parts' => @parts
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should fetch all settings" do
|
33
|
+
Radiant::Config.should_receive(:find_all_as_tree).and_return(@tree)
|
34
|
+
get 'index'
|
35
|
+
assigns[:settings].should_not be_nil
|
36
|
+
response.should be_success
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "GET /admin/settings/new" do
|
41
|
+
it "should show a new setting form" do
|
42
|
+
login_as :admin
|
43
|
+
get 'new'
|
44
|
+
response.should be_success
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "GET /admin/settings/:id/edit" do
|
49
|
+
it "should fetch the desired setting" do
|
50
|
+
Radiant::Config.should_receive(:find).with('123').and_return(@parts)
|
51
|
+
get 'edit', :id => '123'
|
52
|
+
assigns[:setting].should == @parts
|
53
|
+
response.should be_success
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "PUT /admin/settings/:id" do
|
58
|
+
it "should update an existing setting" do
|
59
|
+
Radiant::Config.should_receive(:find).with('123').and_return(@parts)
|
60
|
+
@parts.should_receive(:update_attribute).with(:value, 'body, sidebar')
|
61
|
+
|
62
|
+
put 'update', :id => '123', :setting => { :value => 'body, sidebar' }
|
63
|
+
response.should redirect_to(admin_settings_path)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "DELETE /admin/setting/:id" do
|
68
|
+
it "should destroy the desired setting" do
|
69
|
+
login_as :admin
|
70
|
+
Radiant::Config.should_receive(:find).with('123').and_return(@parts)
|
71
|
+
@parts.should_receive(:destroy)
|
72
|
+
|
73
|
+
delete 'destroy', :id => '123'
|
74
|
+
response.should redirect_to(admin_settings_path)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../../spec_helper"
|
2
|
+
require File.dirname(__FILE__) + "/../../../settings_extension"
|
3
|
+
|
4
|
+
describe Radiant::AdminUI do
|
5
|
+
before :each do
|
6
|
+
@admin = Radiant::AdminUI.instance
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should have a settings Region Set" do
|
10
|
+
@admin.should respond_to(:settings)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should should have regions for the 'index'" do
|
14
|
+
@admin.settings.index.should_not be_nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should have 'top, list, bottom' regions in the 'index main' region" do
|
18
|
+
@admin.settings.index.main.should == %w{top list bottom}
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe "Settings Tags" do
|
4
|
+
dataset :users_and_pages
|
5
|
+
|
6
|
+
describe "<r:config:setting>" do
|
7
|
+
it "should render the Radiant::Config setting specified by the required 'key' attribute." do
|
8
|
+
pages(:home).should render('<r:config:setting key="title" />').as(Radiant::Config['title'])
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should error without the required 'key' attribute." do
|
12
|
+
pages(:home).should render('<r:config:setting />').with_error("'key' attribute required")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Radiant::Config, 'find_all_as_tree' do
|
4
|
+
before do
|
5
|
+
@title = Radiant::Config.create(:key => 'admin.title', :value => 'Radiant CMS')
|
6
|
+
@parts = Radiant::Config.create(:key => 'defaults.page.parts', :value => 'body, extended')
|
7
|
+
@status = Radiant::Config.create(:key => 'defaults.page.status', :value => 'draft')
|
8
|
+
@repetitive = Radiant::Config.create(:key => 'repetitive.setting.setting', :value => 'foo')
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should find all settings and return a tree as a nested hash" do
|
12
|
+
result = Radiant::Config.find_all_as_tree
|
13
|
+
result['admin']['title'].should == @title
|
14
|
+
result['defaults']['page']['parts'].should == @parts
|
15
|
+
result['defaults']['page']['status'].should == @status
|
16
|
+
result['repetitive']['setting']['setting'].should == @repetitive
|
17
|
+
end
|
18
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
unless defined? RADIANT_ROOT
|
2
|
+
ENV["RAILS_ENV"] = "test"
|
3
|
+
case
|
4
|
+
when ENV["RADIANT_ENV_FILE"]
|
5
|
+
require ENV["RADIANT_ENV_FILE"]
|
6
|
+
when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
|
7
|
+
require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../../")}/config/environment"
|
8
|
+
else
|
9
|
+
require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../")}/config/environment"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
require "#{RADIANT_ROOT}/spec/spec_helper"
|
13
|
+
|
14
|
+
Dataset::Resolver.default << (File.dirname(__FILE__) + "/datasets")
|
15
|
+
|
16
|
+
if File.directory?(File.dirname(__FILE__) + "/matchers")
|
17
|
+
Dir[File.dirname(__FILE__) + "/matchers/*.rb"].each {|file| require file }
|
18
|
+
end
|
19
|
+
|
20
|
+
Spec::Runner.configure do |config|
|
21
|
+
# config.use_transactional_fixtures = true
|
22
|
+
# config.use_instantiated_fixtures = false
|
23
|
+
# config.fixture_path = RAILS_ROOT + '/spec/fixtures'
|
24
|
+
|
25
|
+
# You can declare fixtures for each behaviour like this:
|
26
|
+
# describe "...." do
|
27
|
+
# fixtures :table_a, :table_b
|
28
|
+
#
|
29
|
+
# Alternatively, if you prefer to declare them only once, you can
|
30
|
+
# do so here, like so ...
|
31
|
+
#
|
32
|
+
# config.global_fixtures = :table_a, :table_b
|
33
|
+
#
|
34
|
+
# If you declare global fixtures, be aware that they will be declared
|
35
|
+
# for all of your examples, even those that don't use them.
|
36
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../spec_helper'
|
2
|
+
|
3
|
+
describe "/admin/settings/:id/edit" do
|
4
|
+
before do
|
5
|
+
@parts = mock_model(Radiant::Config)
|
6
|
+
@parts.stub!(:key).and_return('defaults.page.parts')
|
7
|
+
@parts.stub!(:value).and_return('body, extended')
|
8
|
+
@parts.stub!(:description).and_return('foo')
|
9
|
+
@parts.stub!(:protected?).and_return(false)
|
10
|
+
@parts.stub!(:protected_value).and_return('body, extended')
|
11
|
+
|
12
|
+
assigns[:setting] = @parts
|
13
|
+
|
14
|
+
render 'admin/settings/edit'
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should have a heading of with setting key that is being edited" do
|
18
|
+
response.should have_tag('h2.setting-name', 'defaults.page.parts')
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should have a description" do
|
22
|
+
response.should have_tag('div.description', 'foo')
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should have a form" do
|
26
|
+
response.should have_tag('form') do |form|
|
27
|
+
form.should have_tag('input', :value => 'body, extended')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../spec_helper'
|
2
|
+
|
3
|
+
describe "/admin/settings/index" do
|
4
|
+
before do
|
5
|
+
assigns[:template_name] = 'index'
|
6
|
+
|
7
|
+
@parts = mock_model(Radiant::Config)
|
8
|
+
@parts.stub!(:key).and_return('defaults.page.parts')
|
9
|
+
@parts.stub!(:value).and_return('body, extended')
|
10
|
+
@parts.stub!(:description).and_return('foo')
|
11
|
+
@parts.stub!(:protected?).and_return(false)
|
12
|
+
@parts.stub!(:protected_value).and_return('body, extended')
|
13
|
+
|
14
|
+
@title = mock_model(Radiant::Config)
|
15
|
+
@title.stub!(:key).and_return('admin.title')
|
16
|
+
@title.stub!(:value).and_return('Radiant CMS')
|
17
|
+
@title.stub!(:description).and_return('bar')
|
18
|
+
@title.stub!(:protected?).and_return(false)
|
19
|
+
@title.stub!(:protected_value).and_return('Radiant CMS')
|
20
|
+
|
21
|
+
@password = mock_model(Radiant::Config)
|
22
|
+
@password.stub!(:key).and_return('account.password')
|
23
|
+
@password.stub!(:value).and_return('super secret')
|
24
|
+
@password.stub!(:description).and_return('password')
|
25
|
+
@password.stub!(:protected?).and_return(true)
|
26
|
+
@password.stub!(:protected_value).and_return('********')
|
27
|
+
|
28
|
+
assigns[:settings] = {
|
29
|
+
'admin' => {
|
30
|
+
'title' => @title
|
31
|
+
},
|
32
|
+
'defaults' => {
|
33
|
+
'page' => {
|
34
|
+
'parts' => @parts
|
35
|
+
}
|
36
|
+
},
|
37
|
+
'account' => {
|
38
|
+
'password' => @password
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
render 'admin/settings/index'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should have a heading of 'Radiant Settings'" do
|
46
|
+
response.should have_tag('h1', 'Radiant Settings')
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should have a table listing all settings" do
|
50
|
+
response.should have_tag('td', 'Defaults')
|
51
|
+
response.should have_tag('td', 'Page')
|
52
|
+
response.should have_tag('td', 'Parts')
|
53
|
+
response.should have_tag('td', 'body, extended')
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should display password settings as '********'" do
|
57
|
+
response.should have_tag('tr') do
|
58
|
+
with_tag('td','Password')
|
59
|
+
with_tag('td', '********')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: radiant-settings-extension
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 17
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
- 1
|
10
|
+
version: 1.1.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Alex Wayne
|
14
|
+
- Jim Gay
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2010-07-05 00:00:00 -04:00
|
20
|
+
default_executable:
|
21
|
+
dependencies: []
|
22
|
+
|
23
|
+
description: Allows users to edit the details of the config table.
|
24
|
+
email: jim@saturnflyer.com
|
25
|
+
executables: []
|
26
|
+
|
27
|
+
extensions: []
|
28
|
+
|
29
|
+
extra_rdoc_files:
|
30
|
+
- README.markdown
|
31
|
+
files:
|
32
|
+
- .gitignore
|
33
|
+
- HELP_admin.md
|
34
|
+
- README.markdown
|
35
|
+
- Rakefile
|
36
|
+
- VERSION
|
37
|
+
- app/controllers/admin/settings_controller.rb
|
38
|
+
- app/helpers/admin/settings_helper.rb
|
39
|
+
- app/views/admin/settings/_setting.html.haml
|
40
|
+
- app/views/admin/settings/edit.html.haml
|
41
|
+
- app/views/admin/settings/index.html.haml
|
42
|
+
- app/views/admin/settings/new.html.haml
|
43
|
+
- config/locales/en.yml
|
44
|
+
- config/routes.rb
|
45
|
+
- cucumber.yml
|
46
|
+
- db/migrate/001_add_description_to_config.rb
|
47
|
+
- db/migrate/002_add_settings_roles.rb
|
48
|
+
- features/support/env.rb
|
49
|
+
- features/support/paths.rb
|
50
|
+
- lib/config_find_all_as_tree.rb
|
51
|
+
- lib/config_protection.rb
|
52
|
+
- lib/settings_tags.rb
|
53
|
+
- lib/tasks/settings_extension_tasks.rake
|
54
|
+
- public/images/.DS_Store
|
55
|
+
- public/images/admin/.DS_Store
|
56
|
+
- public/images/admin/setting.png
|
57
|
+
- settings_extension.rb
|
58
|
+
- spec/controllers/admin/settings_controller_spec.rb
|
59
|
+
- spec/helpers/admin/settings_helper_spec.rb
|
60
|
+
- spec/lib/radiant/admin_ui_spec.rb
|
61
|
+
- spec/lib/settings_tags_spec.rb
|
62
|
+
- spec/models/config_spec.rb
|
63
|
+
- spec/spec.opts
|
64
|
+
- spec/spec_helper.rb
|
65
|
+
- spec/views/admin/settings/edit_view_spec.rb
|
66
|
+
- spec/views/admin/settings/index_view_spec.rb
|
67
|
+
has_rdoc: true
|
68
|
+
homepage: http://github.com/saturnflyer/radiant-settings-extension
|
69
|
+
licenses: []
|
70
|
+
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options:
|
73
|
+
- --charset=UTF-8
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
hash: 3
|
82
|
+
segments:
|
83
|
+
- 0
|
84
|
+
version: "0"
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
hash: 3
|
91
|
+
segments:
|
92
|
+
- 0
|
93
|
+
version: "0"
|
94
|
+
requirements: []
|
95
|
+
|
96
|
+
rubyforge_project:
|
97
|
+
rubygems_version: 1.3.7
|
98
|
+
signing_key:
|
99
|
+
specification_version: 3
|
100
|
+
summary: Settings Extension for Radiant CMS
|
101
|
+
test_files:
|
102
|
+
- spec/controllers/admin/settings_controller_spec.rb
|
103
|
+
- spec/helpers/admin/settings_helper_spec.rb
|
104
|
+
- spec/lib/radiant/admin_ui_spec.rb
|
105
|
+
- spec/lib/settings_tags_spec.rb
|
106
|
+
- spec/models/config_spec.rb
|
107
|
+
- spec/spec_helper.rb
|
108
|
+
- spec/views/admin/settings/edit_view_spec.rb
|
109
|
+
- spec/views/admin/settings/index_view_spec.rb
|