aslakjo-aslakjo-comatose 2.0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/CHANGELOG +195 -0
  2. data/INSTALL +20 -0
  3. data/LICENSE +20 -0
  4. data/MANIFEST +91 -0
  5. data/README.markdown +159 -0
  6. data/Rakefile +176 -0
  7. data/SPECS +61 -0
  8. data/about.yml +7 -0
  9. data/bin/comatose +112 -0
  10. data/comatose.gemspec +113 -0
  11. data/generators/comatose_migration/USAGE +15 -0
  12. data/generators/comatose_migration/comatose_migration_generator.rb +74 -0
  13. data/generators/comatose_migration/templates/migration.rb +35 -0
  14. data/generators/comatose_migration/templates/v4_upgrade.rb +15 -0
  15. data/generators/comatose_migration/templates/v6_upgrade.rb +23 -0
  16. data/generators/comatose_migration/templates/v7_upgrade.rb +22 -0
  17. data/init.rb +2 -0
  18. data/install.rb +18 -0
  19. data/lib/acts_as_versioned.rb +543 -0
  20. data/lib/comatose.rb +33 -0
  21. data/lib/comatose/comatose_drop.rb +79 -0
  22. data/lib/comatose/configuration.rb +69 -0
  23. data/lib/comatose/page_wrapper.rb +119 -0
  24. data/lib/comatose/processing_context.rb +69 -0
  25. data/lib/comatose/tasks/admin.rb +60 -0
  26. data/lib/comatose/tasks/data.rb +82 -0
  27. data/lib/comatose/tasks/setup.rb +52 -0
  28. data/lib/comatose/version.rb +4 -0
  29. data/lib/comatose_admin_controller.rb +395 -0
  30. data/lib/comatose_admin_helper.rb +37 -0
  31. data/lib/comatose_controller.rb +138 -0
  32. data/lib/comatose_helper.rb +3 -0
  33. data/lib/comatose_page.rb +141 -0
  34. data/lib/liquid.rb +52 -0
  35. data/lib/liquid/block.rb +96 -0
  36. data/lib/liquid/context.rb +190 -0
  37. data/lib/liquid/document.rb +17 -0
  38. data/lib/liquid/drop.rb +48 -0
  39. data/lib/liquid/errors.rb +7 -0
  40. data/lib/liquid/extensions.rb +53 -0
  41. data/lib/liquid/file_system.rb +62 -0
  42. data/lib/liquid/htmltags.rb +64 -0
  43. data/lib/liquid/standardfilters.rb +111 -0
  44. data/lib/liquid/standardtags.rb +399 -0
  45. data/lib/liquid/strainer.rb +42 -0
  46. data/lib/liquid/tag.rb +25 -0
  47. data/lib/liquid/template.rb +88 -0
  48. data/lib/liquid/variable.rb +39 -0
  49. data/lib/redcloth.rb +1129 -0
  50. data/lib/support/class_options.rb +36 -0
  51. data/lib/support/inline_rendering.rb +48 -0
  52. data/lib/support/route_mapper.rb +50 -0
  53. data/lib/text_filters.rb +140 -0
  54. data/lib/text_filters/markdown.rb +14 -0
  55. data/lib/text_filters/markdown_smartypants.rb +15 -0
  56. data/lib/text_filters/none.rb +8 -0
  57. data/lib/text_filters/rdoc.rb +13 -0
  58. data/lib/text_filters/simple.rb +8 -0
  59. data/lib/text_filters/textile.rb +15 -0
  60. data/rails/init.rb +3 -0
  61. data/resources/layouts/comatose_admin_template.html.erb +28 -0
  62. data/resources/public/images/collapsed.gif +0 -0
  63. data/resources/public/images/expanded.gif +0 -0
  64. data/resources/public/images/no-children.gif +0 -0
  65. data/resources/public/images/page.gif +0 -0
  66. data/resources/public/images/spinner.gif +0 -0
  67. data/resources/public/images/title-hover-bg.gif +0 -0
  68. data/resources/public/javascripts/comatose_admin.js +401 -0
  69. data/resources/public/stylesheets/comatose_admin.css +404 -0
  70. data/tasks/comatose.rake +9 -0
  71. data/test/behaviors.rb +106 -0
  72. data/test/fixtures/comatose_pages.yml +96 -0
  73. data/test/functional/comatose_admin_controller_test.rb +114 -0
  74. data/test/functional/comatose_controller_test.rb +44 -0
  75. data/test/javascripts/test.html +26 -0
  76. data/test/javascripts/test_runner.js +307 -0
  77. data/test/test_helper.rb +55 -0
  78. data/test/unit/class_options_test.rb +52 -0
  79. data/test/unit/comatose_page_test.rb +136 -0
  80. data/test/unit/processing_context_test.rb +108 -0
  81. data/test/unit/text_filters_test.rb +52 -0
  82. data/views/comatose_admin/_form.html.erb +96 -0
  83. data/views/comatose_admin/_page_list_item.html.erb +60 -0
  84. data/views/comatose_admin/delete.html.erb +18 -0
  85. data/views/comatose_admin/edit.html.erb +5 -0
  86. data/views/comatose_admin/index.html.erb +29 -0
  87. data/views/comatose_admin/new.html.erb +5 -0
  88. data/views/comatose_admin/reorder.html.erb +30 -0
  89. data/views/comatose_admin/versions.html.erb +40 -0
  90. data/views/layouts/comatose_admin.html.erb +837 -0
  91. data/views/layouts/comatose_admin_customize.html.erb +28 -0
  92. data/views/layouts/comatose_content.html.erb +17 -0
  93. metadata +148 -0
@@ -0,0 +1,55 @@
1
+ ENV["RAILS_ENV"] = 'test'
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../../../config/environment.rb'))
4
+
5
+ require 'test/unit'
6
+ require 'test_help'
7
+
8
+ class Test::Unit::TestCase
9
+
10
+ self.fixture_path = File.expand_path( File.join(File.dirname(__FILE__), 'fixtures') )
11
+
12
+ self.use_transactional_fixtures = true
13
+ self.use_instantiated_fixtures = false
14
+
15
+ def setup
16
+ Comatose.configure do |config|
17
+ config.default_filter = :textile
18
+ config.default_processor = :liquid
19
+ config.authorization = Proc.new { true }
20
+ config.admin_authorization = Proc.new { true }
21
+ config.admin_get_author = Proc.new { request.env['REMOTE_ADDR'] }
22
+ config.admin_get_root_page = Proc.new { ComatosePage.root }
23
+ end
24
+ TextFilters.default_filter = "Textile"
25
+ end
26
+
27
+ def create_page(options={})
28
+ ComatosePage.create({ :title => 'Comatose Page', :author=>'test', :parent_id=>1 }.merge(options))
29
+ end
30
+
31
+ def comatose_page(sym)
32
+ ComatosePage.find_by_slug(sym.to_s.dasherize)
33
+ end
34
+
35
+ def assert_difference(object, method = nil, difference = 1)
36
+ initial_value = object.send(method)
37
+ yield
38
+ assert_equal initial_value + difference, object.send(method), "#{object}##{method}"
39
+ end
40
+
41
+ def assert_no_difference(object, method, &block)
42
+ assert_difference object, method, 0, &block
43
+ end
44
+
45
+ class << self
46
+ def should(behave,&block)
47
+ method_name = "test_should_#{behave.gsub(' ', '_')}"
48
+ if block
49
+ define_method method_name, &block
50
+ else
51
+ puts ">>> Untested: #{name.sub(/Test$/,'')} should #{behave}"
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,52 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ require 'support/class_options'
3
+
4
+ class ClassOptionsTest < Test::Unit::TestCase
5
+
6
+ class Opts
7
+ define_option :nothing, nil
8
+ define_option :nada
9
+ define_option :name, "Matt"
10
+ define_option :age, 30
11
+ define_option :mode, :test
12
+ define_option :listing, ['one', 'two', 'three']
13
+ define_option :opts_1, {'one'=>'ONE', 'two'=>'TWO'}
14
+ define_option :opts_2, {:one=>'ONE', :two=>'TWO'}
15
+ define_option :should_work, true
16
+ define_option :would_surprise, false
17
+ end
18
+
19
+ should "allow nil as a default" do
20
+ assert_equal nil, Opts.nothing
21
+ assert_equal nil, Opts.nada
22
+ end
23
+
24
+ should "allow boolean defaults" do
25
+ assert_equal true, Opts.should_work
26
+ assert_equal false, Opts.would_surprise
27
+ end
28
+
29
+ should "allow string defaults" do
30
+ assert_equal 'Matt', Opts.name
31
+ end
32
+
33
+ should "allow numeric defaults" do
34
+ assert_equal 30, Opts.age
35
+ end
36
+
37
+ should "allow symbolic defaults" do
38
+ assert_equal :test, Opts.mode
39
+ end
40
+
41
+ should "allow array literals as defaults" do
42
+ assert_equal ['one', 'two', 'three'], Opts.listing
43
+ end
44
+
45
+ should "allow hash literals as defaults" do
46
+ h1 = {'one'=>'ONE', 'two'=>'TWO'}
47
+ h2 = {:one=>'ONE', :two=>'TWO'}
48
+ assert_equal h1, Opts.opts_1
49
+ assert_equal h2, Opts.opts_2
50
+ end
51
+
52
+ end
@@ -0,0 +1,136 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class ComatosePageTest < Test::Unit::TestCase
4
+
5
+ fixtures :comatose_pages
6
+
7
+ should "create page" do
8
+ assert_difference ComatosePage, :count do
9
+ page = create_page :title=>'New Page Name'
10
+ assert !page.new_record?, "#{page.errors.full_messages.to_sentence}"
11
+ end
12
+ end
13
+
14
+ should "create a new version of an updated page" do
15
+ page = create_page
16
+ assert_difference page, :version do
17
+ page.update_attribute :body, "I'm the new content!"
18
+ assert_equal "<p>I&#8217;m the new content!</p>", page.to_html
19
+ end
20
+ end
21
+
22
+ should "render content through textile and liquid processors" do
23
+ page = create_page :title=>'Title Here', :body=>'h1. {{page.title}}'
24
+ assert_equal "<h1>Title Here</h1>", page.to_html
25
+ end
26
+
27
+ should "not allow creation of page when missing a title" do
28
+ assert_no_difference ComatosePage, :count do
29
+ p = create_page(:title => nil)
30
+ assert p.errors.on(:title)
31
+ end
32
+ end
33
+
34
+ should "have good fixtures for this to work out" do
35
+ assert_equal 'Home Page', root_page.title
36
+ assert_equal 'home-page', root_page.slug
37
+ assert_equal 'Comatose', root_page.author
38
+ assert_equal "", root_page.full_path
39
+ assert_equal 'faq', faq_page.full_path
40
+ end
41
+
42
+ should "generate slugs correctly" do
43
+ assert_equal 'hello-how-are-you', new_page_slug( "Hello, How Are You?" )
44
+ assert_equal 'i-have-too-much-space', new_page_slug( "I have too much space" )
45
+ assert_equal 'i-have-leading-and-trailing-space', new_page_slug( " I have leading and trailing space " )
46
+ assert_equal 'what-about-dashes', new_page_slug( "What about - dashes?" )
47
+ assert_equal 'a-bizarre-title', new_page_slug( 'A !@!@#$%^<>&*()_+{} Bizarre TiTle!' )
48
+ assert_equal '001-numbers-too', new_page_slug( "001 Numbers too" )
49
+ end
50
+
51
+ should "generate page paths correctly" do
52
+ products = root_page.children.create( :title=>'Products' )
53
+ assert_equal 'products', products.full_path
54
+
55
+ books = products.children.create( :title=>'Books' )
56
+ assert_equal 'products/books', books.full_path
57
+
58
+ novels = books.children.create( :title=>'Novels' )
59
+ assert_equal 'products/books/novels', novels.full_path
60
+
61
+ comics = books.children.create( :title=>'Comics' )
62
+ assert_equal 'products/books/comics', comics.full_path
63
+ end
64
+
65
+ should "update page paths when pages are moved" do
66
+ page = comatose_page :params
67
+ assert_equal 'params', page.full_path
68
+
69
+ q1pg = comatose_page :question_one
70
+ page.parent_id = q1pg.id
71
+ assert page.save, "Page.save"
72
+
73
+ page.reload
74
+ assert_equal 'faq/question-one/params', page.full_path
75
+
76
+ q1pg.reload
77
+ q1pg.slug = "q-1"
78
+ assert q1pg.save, "Page.save"
79
+ assert_equal "faq/q-1", q1pg.full_path
80
+
81
+ page.reload
82
+ assert_equal 'faq/q-1/params', page.full_path
83
+ end
84
+
85
+ should "set an AR error with processor syntax error info" do
86
+ page = create_page :title=>'Title Here', :body=>'h1. {% crap %}'
87
+ assert !page.save, page.errors.full_messages.to_sentence
88
+ end
89
+
90
+ should "render body text accurately" do
91
+ assert_equal "<h1>Home Page</h1>\n<p>This is your <strong>home page</strong>.</p>", root_page.to_html
92
+ assert_equal "<h1>Frequently Asked Questions</h1>\n<h2><a href=\"/faq/question-one\">Question One?</a></h2>\n<p>Content for <strong>question one</strong>.</p>\n<h2><a href=\"/faq/question-two\">Question Two?</a></h2>\n<p>Content for <strong>question two</strong>.</p>", faq_page.to_html
93
+ end
94
+
95
+ should "render data from parameterized calls too" do
96
+ assert_equal "<p>I&#8217;m</p>", param_driven_page.to_html
97
+ assert_equal "<p>I&#8217;m From the Params Hash</p>", param_driven_page.to_html(:extra=>'From the Params Hash')
98
+ end
99
+
100
+ should "render data from a Drop" do
101
+ Comatose.define_drop "app" do
102
+ def test
103
+ "From Drop"
104
+ end
105
+ end
106
+ p = create_page(:title=>'Test Drop', :body=>'{{ app.test }}')
107
+ assert_equal "<p>From Drop</p>", p.to_html
108
+ end
109
+
110
+ # Test illustrates broken partial, sort of
111
+ # <%= render :comatose => 'faq/question-one' %> should work, but does not
112
+ should "render inline partial" do
113
+ Comatose.config.default_processor = :erb
114
+ page = create_page :body => "Included: <%= ComatosePage.find_by_path('faq/question-one').to_html %>", :filter_type => :none
115
+ assert_equal "Included: <p>Content for <strong>question one</strong>.</p>", page.to_html
116
+ end
117
+
118
+ protected
119
+
120
+ def new_page_slug(title)
121
+ create_page( :title=>title ).slug
122
+ end
123
+
124
+ def root_page
125
+ ComatosePage.root
126
+ end
127
+
128
+ def faq_page
129
+ comatose_page :faq
130
+ end
131
+
132
+ def param_driven_page
133
+ comatose_page :params
134
+ end
135
+
136
+ end
@@ -0,0 +1,108 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ require 'comatose'
3
+
4
+ class ProcessingContextTest < Test::Unit::TestCase
5
+
6
+ fixtures :comatose_pages
7
+
8
+ def setup
9
+ @root = comatose_page( :home_page )
10
+ @binding = Comatose::ProcessingContext.new(@root)
11
+ end
12
+
13
+ # should "process liquid tags with no filters correctly" do
14
+ # result = TextFilters.transform('{{ page.title }}', @binding, :none, :liquid)
15
+ # assert_equal 'Home Page', result
16
+ # end
17
+ #
18
+ should "process erb tags correctly" do
19
+ result = TextFilters.transform('<%= page.title %>', @binding, :none, :erb)
20
+ assert_equal 'Home Page', result
21
+ end
22
+
23
+ should "support text translation and processing with ERB" do
24
+ src = 'The title is *<%= title %>*'
25
+ if TextFilters.all.keys.include? 'None'
26
+ assert_equal "The title is *Home Page*", TextFilters.transform(src, @binding, :none, :erb)
27
+ end
28
+ if TextFilters.all.keys.include? 'Textile'
29
+ assert_equal "<p>The title is <strong>Home Page</strong></p>", TextFilters.transform(src, @binding, :textile, :erb)
30
+ end
31
+ if TextFilters.all.keys.include? 'Markdown'
32
+ assert_equal "<p>The title is <em>Home Page</em></p>", TextFilters.transform(src, @binding, 'Markdown', :erb)
33
+ end
34
+ if TextFilters.all.keys.include? 'RDoc'
35
+ assert_equal "<p>\nThe title is *Home Page*\n</p>\n", TextFilters.transform(src, @binding, :rdoc, :erb)
36
+ end
37
+ end
38
+
39
+ should "support text translation and processing with Liquid" do
40
+ src = 'The title is *{{ page.title }}*'
41
+ assert_equal "The title is *Home Page*", TextFilters.transform(src, @binding, :none, :liquid)
42
+ if TextFilters.all_titles.include? 'Textile'
43
+ assert_equal "<p>The title is <strong>Home Page</strong></p>", TextFilters.transform(src, @binding, :textile, :liquid)
44
+ end
45
+ if TextFilters.all_titles.include? 'Markdown'
46
+ assert_equal "<p>The title is <em>Home Page</em></p>", TextFilters.transform(src, @binding, :markdown, :liquid)
47
+ end
48
+ if TextFilters.all_titles.include? 'RDoc'
49
+ assert_equal "<p>\nThe title is *Home Page*\n</p>\n", TextFilters.transform(src, @binding, :rdoc, :liquid)
50
+ end
51
+ end
52
+
53
+ UNSAFE_PROPS = %w(version position)
54
+ SAFE_PROPS = %w(id full_path uri slug keywords title to_html filter_type author updated_on created_on)
55
+
56
+ should "allow access to safe properties and methods when processing with ERB" do
57
+ binding = Comatose::ProcessingContext.new( comatose_page(:faq) )
58
+ SAFE_PROPS.each do |prop|
59
+ assert_not_equal '', TextFilters.transform("<%= page.#{prop} %>", binding, :none, :liquid), "on page.#{prop}"
60
+ end
61
+ end
62
+
63
+ should "prevent access to protected properties and methods when processing with ERB" do
64
+ binding = Comatose::ProcessingContext.new( comatose_page(:faq) )
65
+ UNSAFE_PROPS.each do |prop|
66
+ assert_equal "<%= page.#{prop} %>", TextFilters.transform("<%= page.#{prop} %>", binding, :none, :liquid), "on page.#{prop}"
67
+ end
68
+ end
69
+
70
+ should "allow access to safe properties and methods when processing with Liquid" do
71
+ binding = Comatose::ProcessingContext.new( comatose_page(:faq) )
72
+ SAFE_PROPS.each do |prop|
73
+ assert_not_equal '', TextFilters.transform("{{ page.#{prop} }}", binding, :none, :liquid), "on page.#{prop}"
74
+ end
75
+ end
76
+
77
+ should "prevent access to protected properties and methods when processing with Liquid" do
78
+ binding = Comatose::ProcessingContext.new( comatose_page(:faq) )
79
+ UNSAFE_PROPS.each do |prop|
80
+ assert_equal '', TextFilters.transform("{{ page.#{prop} }}", binding, :none, :liquid), "on page.#{prop}"
81
+ end
82
+ end
83
+
84
+ should "allow referenceing of defined ComatoseDrops" do
85
+ Comatose.define_drop "app" do
86
+ def test
87
+ "TEST"
88
+ end
89
+ end
90
+
91
+ result = TextFilters.transform('{{ app.test }}', @binding, :none, :liquid)
92
+ assert_equal 'TEST', result
93
+
94
+ result2 = TextFilters.transform('<%= app.test %>', @binding, :none, :erb)
95
+ assert_equal 'TEST', result2
96
+ end
97
+
98
+ should "let ComatoseDrop errors bubble upward" do
99
+ Comatose.define_drop "broken" do
100
+ def test
101
+ "TEST #{crap}"
102
+ end
103
+ end
104
+
105
+ assert_raise(RuntimeError) { TextFilters.transform('{{ broken.test }}', @binding, :none, :liquid) }
106
+ end
107
+
108
+ end
@@ -0,0 +1,52 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ require 'erb'
4
+ require 'liquid'
5
+
6
+ require 'text_filters'
7
+ # require 'comatose/page'
8
+ # require 'comatose/processing_context'
9
+
10
+ class TextFiltersTest < Test::Unit::TestCase
11
+ # fixtures :comatose_pages
12
+ # self.use_instantiated_fixtures = true
13
+
14
+ should "not alter output when using filter :none" do
15
+ assert_equal "line one\nline two", TextFilters.render_text("line one\nline two", :none)
16
+ end
17
+
18
+ should "convert newlines into <br/>s when using :simple filter" do
19
+ assert_equal "line one<br/>line two", TextFilters.render_text("line one\nline two", :simple)
20
+ end
21
+
22
+ should "support Textile, if it's available, using :textile or 'Textile' as a key" do
23
+ if TextFilters.all.keys.include? 'Textile'
24
+ assert_equal "<p>testing <strong>bold</strong></p>", TextFilters.render_text("testing *bold*", :textile)
25
+ assert_equal "<p>testing <strong>bold</strong></p>", TextFilters.render_text("testing *bold*", 'Textile')
26
+ end
27
+ end
28
+
29
+ should "support Markdown, if it's available, using :markdown or 'Markdown' as a key" do
30
+ if TextFilters.all.keys.include? 'Markdown'
31
+ assert_equal "<p>testing <em>bold</em></p>", TextFilters.render_text("testing *bold*", :markdown)
32
+ end
33
+ end
34
+
35
+ should "support RDoc, if it's available, using :rdoc or 'RDoc' as a key" do
36
+ if TextFilters.all.keys.include? 'RDoc'
37
+ assert_equal "<p>\ntesting <b>bold</b>\n</p>\n", TextFilters.render_text("testing *bold*", :rdoc)
38
+ assert_equal "<p>\ntesting <b>bold</b>\n</p>\n", TextFilters.render_text("testing *bold*", 'RDoc')
39
+ end
40
+ end
41
+
42
+ should "support transformation of parameters via ERB" do
43
+ src = 'Hello, <%= name %>'
44
+ assert_equal "Hello, Matt", TextFilters.transform(src, {'name'=>'Matt'}, :none, :erb)
45
+ end
46
+
47
+ should "support transformation of parameters via Liquid" do
48
+ src = 'Hello, {{ name }}'
49
+ assert_equal "Hello, Matt", TextFilters.transform(src, {'name'=>'Matt'}, :none, :liquid)
50
+ end
51
+
52
+ end
@@ -0,0 +1,96 @@
1
+ <%= error_messages_for :page %>
2
+
3
+ <% form_for :page, @page do |f| %>
4
+ <table class="page-form" cellpadding="0" cellspacing="0">
5
+
6
+ <tr>
7
+ <td class="label"><label for="page_title">Title</label></td>
8
+ <td class="field"><%= f.text_field :title, :tabindex=>1, :maxlength=>255, :size=>50 %> <%= link_to_function "More...", "ComatoseEditForm.toggle_extra_fields(this)", :id=>'more-options' %></td>
9
+ </tr>
10
+
11
+ <tr id="slug_row" class="meta-info">
12
+ <td class="label"><label for="page_slug">Slug</label></td>
13
+ <td class="field"><%= f.text_field :slug, :tabindex=>6, :maxlength=>255, :size=>50, :disabled=>@root_pages.include?(@page) %></td>
14
+ </tr>
15
+
16
+ <% if show_field? 'keywords' %>
17
+ <tr id="keywords_row" class="meta-info">
18
+ <td class="label"><label for="page_keywords">Keywords</label></td>
19
+ <td class="field"><%= f.text_field :keywords, :tabindex=>7, :maxlength=>1000, :size=>50 %></td>
20
+ </tr>
21
+ <% end %>
22
+
23
+ <% if show_field? 'parent' %>
24
+ <tr id="parent_row" class="meta-info">
25
+ <td class="label"><label for="page_parent">Parent</label></td>
26
+ <td class="field">
27
+ <% if mode != :new and @root_pages.include? @page %>
28
+ <select id="page_parent" disabled="true"><option><%= @page.title %> is a root page</option></select>
29
+ <% else %>
30
+ <select id="page_parent" name="page[parent_id]" tabindex="8"><%= tree_select_box @root_pages, @page.parent_id, @page.id %></select>
31
+ <% end %>
32
+ </td>
33
+ </tr>
34
+ <% end %>
35
+
36
+ <tr>
37
+ <td class="label body"><label for="page_body">Body</label></td>
38
+ <td class="field"><%= f.text_area :body, :rows=>20, :tabindex=>2 %></td>
39
+ </tr>
40
+
41
+ <% if show_field? 'filter' %>
42
+ <tr id="filter_row" class="meta-info">
43
+ <td class="label"><label for="page_filter_type">Filter</label></td>
44
+ <td class="field">
45
+ <%= select_tag 'page[filter_type]', options_for_select(TextFilters.all_titles.sort, @page.filter_type || Comatose.config.default_filter), :tabindex=>3, :id=>'page_filter_type' %>
46
+ <span class="field-help">Converts plain text into html</span>
47
+ </td>
48
+ </tr>
49
+ <% end %>
50
+
51
+ <% if show_field? 'created_on' %>
52
+ <tr id="created_row" class="meta-info">
53
+ <td class="label"><label for="page_created_on">Created</label></td>
54
+ <td class="field">
55
+ <%= f.datetime_select :created_on %>
56
+ </td>
57
+ </tr>
58
+ <% end %>
59
+
60
+ </table>
61
+
62
+ <div id="button-group">
63
+ <% unless @page.updated_on.nil? %>
64
+ <div class="last-update">
65
+ <label>
66
+ Updated <%= time_ago_in_words @page.updated_on, true %> ago by
67
+ <%= @page.author %>.
68
+ <%= link_to(pluralize(@page.versions.length, 'revision', 'revisions'), :action=>'versions', :id=>@page) if @page.versions.length > 0 %>
69
+ </label>
70
+ </div>
71
+ <% end %>
72
+ <%= image_tag 'comatose/spinner.gif', :id=>'spinner', :align=>'absmiddle', :style=>'display:none;' %>
73
+ <%= button_to_function('Preview', "ComatoseEditForm.preview_content('#{url_for :controller=>controller.controller_name, :action=>'preview', :id=>@page}')", :tabindex=>3, :id=>'preview-btn' ) if show_field? 'preview' %> &nbsp;
74
+ <%= submit_tag ((mode == :edit) ? 'Save Changes' : 'Create Page'), :tabindex=>4 %>
75
+ <% if @page.versions.length > 0 %>
76
+ &nbsp; <%= link_to "Revert", :action=>'versions', :id=>@page %>
77
+ <% end %>
78
+ or
79
+ <a href="<%= url_for :controller=>controller.controller_name, :action=>'index' %>" onlick="ComatoseEditForm.cancel(this.href); return false;" tabindex="5">Cancel</a>
80
+ </div>
81
+ <% end %>
82
+
83
+ <div id="preview-area">
84
+ <fieldset>
85
+ <legend>Page Preview</legend>
86
+ <div class="preview-body">
87
+ <div id="preview-panel"><span style='color:blue;'>Loading Preview...</span></div>
88
+ <div style="clear:both"></div>
89
+ </div>
90
+ </fieldset>
91
+ <div class="commands">
92
+ <a href="#" onclick="$('preview-area').hide();">Close Preview</a> or <a href="#">Back to top</a>
93
+ </div>
94
+ </div>
95
+
96
+ <%= javascript_tag "ComatoseEditForm.init('#{mode.to_s}');" %>