radiant-concurrent_draft-extension 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/HELP.rdoc +32 -0
- data/README.textile +52 -0
- data/Rakefile +136 -0
- data/VERSION +1 -0
- data/app/views/admin/_draft_controls.html.haml +85 -0
- data/app/views/admin/_edit_buttons.html.haml +10 -0
- data/app/views/admin/layouts/_edit_content.html.haml +5 -0
- data/app/views/admin/page_parts/_page_part.html.haml +20 -0
- data/app/views/admin/pages/_edit_layout_and_type.html.haml +11 -0
- data/app/views/admin/pages/_published_meta.html.haml +4 -0
- data/app/views/admin/snippets/_edit_content.html.haml +5 -0
- data/app/views/admin/users/_edit_roles.html.haml +26 -0
- data/concurrent_draft_extension.rb +30 -0
- data/config/initializers/radiant_config.rb +3 -0
- data/config/locales/en.yml +11 -0
- data/config/routes.rb +9 -0
- data/db/migrate/001_update_schemata.rb +29 -0
- data/db/migrate/002_create_draft_page_elements.rb +10 -0
- data/db/migrate/003_add_publisher_role.rb +9 -0
- data/lib/concurrent_draft/admin_controller_extensions.rb +52 -0
- data/lib/concurrent_draft/helper_extensions.rb +39 -0
- data/lib/concurrent_draft/model_extensions.rb +77 -0
- data/lib/concurrent_draft/page_extensions.rb +28 -0
- data/lib/concurrent_draft/site_controller_extensions.rb +16 -0
- data/lib/concurrent_draft/tags.rb +56 -0
- data/lib/tasks/concurrent_draft_extension_tasks.rake +46 -0
- data/public/images/admin/cancel.png +0 -0
- data/public/images/admin/clock.png +0 -0
- data/public/images/admin/page_delete.png +0 -0
- data/public/images/admin/page_edit.png +0 -0
- data/public/images/admin/page_refresh.png +0 -0
- data/public/images/admin/tick.png +0 -0
- data/public/javascripts/admin/concurrent_draft.js +72 -0
- data/public/stylesheets/admin/concurrent_draft.css +74 -0
- data/spec/controllers/admin_controller_extensions_spec.rb +184 -0
- data/spec/controllers/site_controller_extensions_spec.rb +31 -0
- data/spec/matchers/concurrent_draft_matcher.rb +11 -0
- data/spec/models/model_extensions_spec.rb +114 -0
- data/spec/models/page_extensions_spec.rb +56 -0
- data/spec/models/tags_spec.rb +43 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +38 -0
- data/test/helpers/caching_test_helper.rb +42 -0
- data/test/helpers/page_part_test_helper.rb +49 -0
- data/test/helpers/page_test_helper.rb +77 -0
- data/vendor/plugins/12_hour_time/CHANGELOG +2 -0
- data/vendor/plugins/12_hour_time/README +16 -0
- data/vendor/plugins/12_hour_time/Rakefile +22 -0
- data/vendor/plugins/12_hour_time/init.rb +1 -0
- data/vendor/plugins/12_hour_time/lib/12_hour_time.rb +78 -0
- data/vendor/plugins/12_hour_time/test/12_hour_time_test.rb +52 -0
- data/vendor/plugins/12_hour_time/test/test_helper.rb +3 -0
- metadata +143 -0
data/HELP.rdoc
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
The <b>ConcurrentDraft</b> extension enables draft versions of pages, snippets and layouts, which can be scheduled for promotion to Production. Every such artifact (page, snippet or layout) can have a concurrent draft version, which will be displayed in development mode, and a promoted live version, which will be displayed in production mode. The admin edit page for each artifact will show the draft version.
|
2
|
+
|
3
|
+
== Usage
|
4
|
+
|
5
|
+
* At the upper right-hand corner of each edit screen (Page, Layout, Snippet), you will find:
|
6
|
+
|
7
|
+
<b>Draft Controls ></b> <em>current status</em>
|
8
|
+
|
9
|
+
* To the right of the label is a link which will show the current status, e.g. 'Unpublished', 'Draft promotion unscheduled', or 'Scheduled 03/21/11 01:00PM'.
|
10
|
+
* Clicking on the status link will display a dropdown of currently available functions.
|
11
|
+
|
12
|
+
== Functions
|
13
|
+
|
14
|
+
=== Promote Now
|
15
|
+
|
16
|
+
This promotes the saved draft version of your artifact to production immediately. Remember that you must save your artifact first.
|
17
|
+
|
18
|
+
=== Schedule Promotion
|
19
|
+
|
20
|
+
This spawns a popup window which enables you set the promotion date and time of your artifact. Upon completion, the status link will show 'Scheduled ...' with the date and time. When the page is accessed on or after that time, the draft will be promoted.
|
21
|
+
|
22
|
+
=== Cancel Promotion
|
23
|
+
|
24
|
+
This cancels a scheduled promotion, and returns the artifact to its previous status.
|
25
|
+
|
26
|
+
=== Unpublish
|
27
|
+
|
28
|
+
This takes a published page and changes it back to 'Draft' status. It will still appear in development mode, but not in production mode until it is published again.
|
29
|
+
|
30
|
+
=== Revert Draft
|
31
|
+
|
32
|
+
This will overlay the current draft with the promoted production version. This is a safety feature which enables you to 'start over' if you have worked on some draft changes and want to go back to square one.
|
data/README.textile
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
h2. Concurrent Draft
|
2
|
+
|
3
|
+
The *ConcurrentDraft* extension enables draft versions of pages, snippets and layouts, which can be scheduled for promotion to Production. Every such artifact (page, snippet or layout) can have a concurrent draft version, which will be displayed in development mode, and a promoted live version, which will be displayed in production mode.
|
4
|
+
|
5
|
+
Created by: Andrew vonderLuft and Sean Cribbs, August 2008, in Portland Oregon
|
6
|
+
|
7
|
+
h3. Version History
|
8
|
+
|
9
|
+
* 1.0.0 - Compatible with Blade UI - 0.9 and above
|
10
|
+
* 0.8.0 - Compatible with Radiant 0.8.0 and above
|
11
|
+
* 0.7.1 - Compatible with Radiant 0.7.1
|
12
|
+
|
13
|
+
h3. Requirements
|
14
|
+
|
15
|
+
* Radiant 0.7 or greater
|
16
|
+
|
17
|
+
h3. Installation
|
18
|
+
|
19
|
+
h4. With the Radiant Extensions registry:
|
20
|
+
|
21
|
+
* From your Radiant root run:
|
22
|
+
|
23
|
+
<pre>script/extension install concurrent_draft
|
24
|
+
rake radiant:extensions:concurrent_draft:migrate
|
25
|
+
rake radiant:extensions:concurrent_draft:update
|
26
|
+
</pre>
|
27
|
+
|
28
|
+
* Restart your radiant app, and you should be good to go.
|
29
|
+
|
30
|
+
h4. Using the gem
|
31
|
+
|
32
|
+
* Install the gem
|
33
|
+
|
34
|
+
<pre>gem install radiant-concurrent_draft-extension</pre>
|
35
|
+
|
36
|
+
* Update your Radiant config: add to environment.rb with other gem.configs
|
37
|
+
|
38
|
+
<pre>config.gem 'radiant-concurrent_draft-extension', :lib => false</pre>
|
39
|
+
|
40
|
+
|
41
|
+
h3. Caveats
|
42
|
+
|
43
|
+
Scheduled times are dependent on the ActiveRecord time setting. If you want to use local time, add this to your environment.rb:
|
44
|
+
|
45
|
+
<pre>config.active_record.default_timezone = :local</pre>
|
46
|
+
|
47
|
+
h3. Acknowledgments
|
48
|
+
|
49
|
+
* Andrew conceived of the ideas for this extension and its initial design, and did model changes, migrations, and initial code for pages.
|
50
|
+
* Sean collaborated on its expansion and refactoring to include snippets and layouts, and produced most of the final code, including all of the UI.
|
51
|
+
* Andrew refactored the UI for Radiant 0.9 and higher, added i18n, and gemified the extension.
|
52
|
+
* After some discussion, they rightly identified the mystery piece as a Haydn Cello concerto.
|
data/Rakefile
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gem|
|
4
|
+
gem.name = "radiant-concurrent_draft-extension"
|
5
|
+
gem.summary = %Q{Concurrent Draft Extension for Radiant CMS}
|
6
|
+
gem.description = %Q{Enables draft versions of pages, snippets and layouts, which can be scheduled for promotion.}
|
7
|
+
gem.email = "avonderluft@avlux.net"
|
8
|
+
gem.homepage = "https://github.com/avonderluft/radiant-concurrent_draft-extension"
|
9
|
+
gem.authors = ['Andrew vonderLuft','Sean Cribbs']
|
10
|
+
gem.add_dependency 'radiant', ">=0.9.1"
|
11
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
12
|
+
end
|
13
|
+
rescue LoadError
|
14
|
+
puts "Jeweler (or a dependency) not available. This is only required if you plan to package concurrent_draft as a gem."
|
15
|
+
end
|
16
|
+
|
17
|
+
# I think this is the one that should be moved to the extension Rakefile template
|
18
|
+
|
19
|
+
# In rails 1.2, plugins aren't available in the path until they're loaded.
|
20
|
+
# Check to see if the rspec plugin is installed first and require
|
21
|
+
# it if it is. If not, use the gem version.
|
22
|
+
|
23
|
+
# Determine where the RSpec plugin is by loading the boot
|
24
|
+
unless defined? RADIANT_ROOT
|
25
|
+
ENV["RAILS_ENV"] = "test"
|
26
|
+
case
|
27
|
+
when ENV["RADIANT_ENV_FILE"]
|
28
|
+
require File.dirname(ENV["RADIANT_ENV_FILE"]) + "/boot"
|
29
|
+
when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
|
30
|
+
require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot"
|
31
|
+
else
|
32
|
+
require "#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'rake'
|
37
|
+
require 'rake/rdoctask'
|
38
|
+
require 'rake/testtask'
|
39
|
+
|
40
|
+
rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
|
41
|
+
$LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
|
42
|
+
require 'spec/rake/spectask'
|
43
|
+
# require 'spec/translator'
|
44
|
+
|
45
|
+
# Cleanup the RADIANT_ROOT constant so specs will load the environment
|
46
|
+
Object.send(:remove_const, :RADIANT_ROOT)
|
47
|
+
|
48
|
+
extension_root = File.expand_path(File.dirname(__FILE__))
|
49
|
+
|
50
|
+
task :default => :spec
|
51
|
+
task :stats => "spec:statsetup"
|
52
|
+
|
53
|
+
desc "Run all specs in spec directory"
|
54
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
55
|
+
t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
|
56
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
57
|
+
end
|
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
|
+
# Hopefully no one has written their extensions in pre-0.9 style
|
83
|
+
# desc "Translate specs from pre-0.9 to 0.9 style"
|
84
|
+
# task :translate do
|
85
|
+
# translator = ::Spec::Translator.new
|
86
|
+
# dir = RAILS_ROOT + '/spec'
|
87
|
+
# translator.translate(dir, dir)
|
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 concurrent_draft extension.'
|
119
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
120
|
+
rdoc.rdoc_dir = 'rdoc'
|
121
|
+
rdoc.title = 'ConcurrentDraftExtension'
|
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 concurrent_draft 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.0.0
|
@@ -0,0 +1,85 @@
|
|
1
|
+
- include_javascript 'admin/concurrent_draft'
|
2
|
+
- resource = "#{@controller.model.display_name} #{@controller.model_class.to_s.downcase}"
|
3
|
+
|
4
|
+
.draft_controls
|
5
|
+
%table.index
|
6
|
+
%tr
|
7
|
+
%td.label Draft Controls >
|
8
|
+
%td.actions
|
9
|
+
- if @controller.model.has_draft_promotion_scheduled?
|
10
|
+
= link_to t('scheduled') + ' ' + @controller.model.draft_promotion_scheduled_at.strftime('%m/%d/%y %I:%M%p'), "#draft_options", :class => "action dropdown"
|
11
|
+
- elsif @controller.model.publishable? && ! @controller.model.published?
|
12
|
+
%em= link_to t('unpublished'), "#draft_options", :class => "action dropdown"
|
13
|
+
- else
|
14
|
+
%em= link_to t('draft_promotion_unscheduled'), "#draft_options", :class => "action dropdown"
|
15
|
+
%ul.menu{:id => "draft_options"}
|
16
|
+
- if @controller.authorized_user?
|
17
|
+
%li.schedule_draft= link_to image('clock') + ' ' + t('schedule_promotion'), '#schedule-draft-popup', :class => 'popup'
|
18
|
+
%li.publish
|
19
|
+
- form_for @controller.model, :url => {:action => 'schedule_draft_promotion', :commit => @controller.model_class.promote_now_text}, :html => {:method => :post} do |f|
|
20
|
+
= link_to_function image('tick') + ' ' + t('promote_now'), "$(this).up('form').submit();showStatus('Promoting #{resource}', true)"
|
21
|
+
- if @controller.model.has_draft_promotion_scheduled?
|
22
|
+
%li.cancel
|
23
|
+
- form_for @controller.model, :url => {:action => 'schedule_draft_promotion', :commit => @controller.model_class.cancel_promotion_text}, :html => {:method => :post} do |f|
|
24
|
+
= link_to_function image('cancel') + ' ' + t('cancel_promotion'), "$(this).up('form').submit();showStatus('Canceling scheduled promotion of #{resource}', true)"
|
25
|
+
- if @controller.model.publishable? && @controller.model.published?
|
26
|
+
%li.unpublish
|
27
|
+
- form_for @controller.model, :url => {:action => 'unpublish', :method => :post} do |f|
|
28
|
+
= link_to_function image('page_delete') + ' ' + t('unpublish'), "$(this).up('form').submit();showStatus('Unpublishing #{resource}', true)"
|
29
|
+
- if @controller.model.has_draft_promoted?
|
30
|
+
%li.revert= link_to image('page_refresh') + ' ' + t('revert_draft'), '#revert-draft-popup', :class => 'popup'
|
31
|
+
|
32
|
+
- content_for :popups do
|
33
|
+
- if @controller.authorized_user?
|
34
|
+
.popup#schedule-draft-popup{:style => 'display:none'}
|
35
|
+
%h3.title
|
36
|
+
= image('clock')
|
37
|
+
= t('schedule_promotion')
|
38
|
+
- form_for @controller.model, :url => {:action => 'schedule_draft_promotion'}, :html => {:method => :post, 'data-onsubmit_status' => "Scheduling promotion of #{resource}"} do |f|
|
39
|
+
%div
|
40
|
+
= f.datetime_select :draft_promotion_scheduled_at, :start_year => Date.today.year, :minute_step => 15, :twelve_hour => true
|
41
|
+
= hidden_field_tag :commit, @controller.model_class.schedule_promotion_text
|
42
|
+
%p{:style => 'text-align: right'}
|
43
|
+
%button{:type => 'submit'}= t('schedule')
|
44
|
+
= t('or')
|
45
|
+
= link_to_function t('cancel'), "$(this).closePopup();"
|
46
|
+
|
47
|
+
.popup#revert-draft-popup{:style => 'display:none'}
|
48
|
+
%p.revert
|
49
|
+
= image('page_refresh')
|
50
|
+
The draft has been replaced with the live content.
|
51
|
+
%br/
|
52
|
+
%br/
|
53
|
+
%em You must save the page for this to take effect.
|
54
|
+
%span{:style => 'padding-left:8px'}= link_to_function 'OK', "$(this).closePopup();"
|
55
|
+
|
56
|
+
- content_for :page_css do
|
57
|
+
:sass
|
58
|
+
.draft_controls
|
59
|
+
float: right
|
60
|
+
width: 300px
|
61
|
+
background: #7E7E7E
|
62
|
+
table.index
|
63
|
+
margin: 0
|
64
|
+
border: none
|
65
|
+
tr, td.label, td.actions
|
66
|
+
border: none
|
67
|
+
padding: 0px
|
68
|
+
background: #7E7E7E
|
69
|
+
td.label
|
70
|
+
text-align: right
|
71
|
+
padding-right: 6px
|
72
|
+
td.actions
|
73
|
+
width: 178px
|
74
|
+
a.action, span.action.disabled
|
75
|
+
color: white
|
76
|
+
text-decoration: underline
|
77
|
+
margin: 0
|
78
|
+
&:hover
|
79
|
+
color: black
|
80
|
+
text-decoration: none
|
81
|
+
background: #eee image_url('admin/buttons_background.png') repeat-x
|
82
|
+
&.selected
|
83
|
+
color: black
|
84
|
+
text-decoration: none
|
85
|
+
background: #c5e0f5
|
@@ -0,0 +1,10 @@
|
|
1
|
+
- if @controller.model.is_a?(Page)
|
2
|
+
- @buttons_partials.each do |partial|
|
3
|
+
= render :partial => partial
|
4
|
+
%p.buttons
|
5
|
+
= save_model_and_continue_editing_button(@controller.model)
|
6
|
+
= save_model_button(@controller.model)
|
7
|
+
- if @controller.authorized_user?
|
8
|
+
= save_model_and_promote_button(@controller.model)
|
9
|
+
or
|
10
|
+
= link_to t('cancel'), :action => 'index'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
.page{:id => "page_#{page_part.name.to_slug}", 'data-caption'=>h(page_part.name)}
|
2
|
+
.part{:id => "part-#{page_part.name.to_slug}"}
|
3
|
+
= hidden_field_tag "page[parts_attributes][#{page_part_counter}][name]", page_part.name, :id => "part_#{page_part.name.to_slug}_name"
|
4
|
+
= hidden_field_tag "page[parts_attributes][#{page_part_counter}][id]", page_part.id, :id => "part_#{page_part_counter}_id", :class => "id_input" unless page_part.new_record?
|
5
|
+
= hidden_field_tag "page[parts_attributes][#{page_part_counter}][_destroy]", page_part._destroy, :class => "delete_input"
|
6
|
+
%p
|
7
|
+
%label{:for => "part_#{page_part.name.to_slug}_filter_id"}
|
8
|
+
= t('filter')
|
9
|
+
= select_tag "page[parts_attributes][#{page_part_counter}][filter_id]", filter_options_for_select(page_part.filter_id), :id => "part_#{page_part.name.to_slug}_filter_id"
|
10
|
+
%span.reference_links
|
11
|
+
= t('reference')
|
12
|
+
%span{:id => "filter_reference_link_#{page_part.name.to_slug}"}
|
13
|
+
= link_to_function t('filter'), "loadFilterReference('#{page_part.name.to_slug}');"
|
14
|
+
%span{:id => "tag_reference_link_#{page_part.name.to_slug}"}
|
15
|
+
= link_to_function t('available_tags'), "loadTagReference('#{page_part.name.to_slug}');"
|
16
|
+
= render_region :part_controls, :locals => {:page_part => page_part}
|
17
|
+
%div
|
18
|
+
~ text_area_tag "page[parts_attributes][#{page_part_counter}][draft_content]", page_part.draft_content, :class => "textarea large", :style => "width: 100%", :id => "part_#{page_part.name.to_slug}_draft_content"
|
19
|
+
= preserve do
|
20
|
+
= hidden_field_tag "page[parts_attributes][#{page_part_counter}][content]", page_part.content, :id => "part_#{page_part.name.to_slug}_content"
|
@@ -0,0 +1,11 @@
|
|
1
|
+
.row
|
2
|
+
%p
|
3
|
+
%label{:for=>"page_layout_id"}
|
4
|
+
Layout
|
5
|
+
= select "page", "layout_id", [['<inherit>', '']] + Layout.find(:all).map { |s| [s.name, s.id] }
|
6
|
+
%p
|
7
|
+
%label{:for=>"page_class_name"}
|
8
|
+
Page Type
|
9
|
+
= select "page", "class_name", [['<normal>', 'Page']] + Page.descendants.map { |p| [p.display_name, p.name] }.sort_by { |p| p.first }
|
10
|
+
= render_region :layout_row
|
11
|
+
%span.clear
|
@@ -0,0 +1,26 @@
|
|
1
|
+
- if @user.respond_to?(:designer)
|
2
|
+
%p
|
3
|
+
%label.multi_option Roles
|
4
|
+
= check_box "user", "admin", :class => "checkbox"
|
5
|
+
%label{:for=> :user_admin, :class => "checkbox"} Administrator
|
6
|
+
= check_box "user", "designer", :class => "checkbox"
|
7
|
+
%label{:for=> :user_designer, :class => "checkbox"} Designer
|
8
|
+
= check_box "user", "publisher", :class => "checkbox"
|
9
|
+
%label{:for=> :user_publisher, :class => "checkbox"} Publisher
|
10
|
+
- elsif @user.respond_to?(:developer)
|
11
|
+
%tr
|
12
|
+
%th.label
|
13
|
+
%label{:for=>"user_admin"} Roles
|
14
|
+
%td.field
|
15
|
+
%span.checkbox
|
16
|
+
= check_box "user", "admin"
|
17
|
+
%label{:for=> "user_admin"} Administrator
|
18
|
+
%span.checkbox
|
19
|
+
= check_box "user", "developer"
|
20
|
+
%label{:for=> "user_developer"} Developer
|
21
|
+
%span.checkbox
|
22
|
+
= check_box "user", "publisher"
|
23
|
+
%label{:for=>"user_publisher"} Publisher
|
24
|
+
%td.help
|
25
|
+
Roles restrict user privileges and turn parts of the administrative interface on or off.
|
26
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Uncomment this if you reference any of your controllers in activate
|
2
|
+
require_dependency 'application_controller'
|
3
|
+
|
4
|
+
class ConcurrentDraftExtension < Radiant::Extension
|
5
|
+
version "#{File.read(File.expand_path(File.dirname(__FILE__)) + '/VERSION')}"
|
6
|
+
description "Enables default draft versions of pages, snippets and layouts, which can be scheduled for promotion to Production"
|
7
|
+
url "https://github.com/avonderluft/radiant-concurrent_draft-extension/tree/master"
|
8
|
+
|
9
|
+
def activate
|
10
|
+
[Page, Snippet, Layout, PagePart].each do |klass|
|
11
|
+
klass.send :include, ConcurrentDraft::ModelExtensions
|
12
|
+
end
|
13
|
+
Page.send :include, ConcurrentDraft::PageExtensions
|
14
|
+
Page.send :include, ConcurrentDraft::Tags
|
15
|
+
[Admin::PagesController, Admin::SnippetsController, Admin::LayoutsController].each do |klass|
|
16
|
+
klass.send :include, ConcurrentDraft::AdminControllerExtensions
|
17
|
+
klass.class_eval do
|
18
|
+
helper ConcurrentDraft::HelperExtensions
|
19
|
+
end
|
20
|
+
end
|
21
|
+
SiteController.send :include, ConcurrentDraft::SiteControllerExtensions
|
22
|
+
%w{page snippet layout}.each do |view|
|
23
|
+
admin.send(view).edit.add :main, "admin/draft_controls", :before => "edit_header"
|
24
|
+
admin.send(view).edit.form_bottom.delete 'edit_buttons'
|
25
|
+
admin.send(view).edit.add :form_bottom, 'admin/edit_buttons'
|
26
|
+
end
|
27
|
+
admin.page.edit.add :extended_metadata, 'published_meta'
|
28
|
+
Time::DATE_FORMATS[:long_civilian] = lambda {|time| time.strftime("%B %d, %Y %I:%M%p").gsub(/(\s+)0(\d+)/, '\1\2') }
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
---
|
2
|
+
en:
|
3
|
+
cancel_promotion: "Cancel promotion"
|
4
|
+
draft_promotion_unscheduled: "Draft promotion unscheduled"
|
5
|
+
promote_now: "Promote now"
|
6
|
+
revert_draft: "Revert draft"
|
7
|
+
schedule: "Schedule"
|
8
|
+
scheduled: "Scheduled"
|
9
|
+
schedule_promotion: "Schedule promotion"
|
10
|
+
unpublish: "Unpublish"
|
11
|
+
unpublished: "Unpublished"
|