liquid_cms 0.2.0.13 → 0.2.1.0

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.
Files changed (55) hide show
  1. data/CHANGELOG.rdoc +12 -0
  2. data/app/controllers/cms/assets_controller.rb +32 -10
  3. data/app/controllers/cms/components_controller.rb +3 -3
  4. data/app/controllers/cms/main_controller.rb +2 -0
  5. data/app/controllers/cms/pages_controller.rb +2 -2
  6. data/app/helpers/cms/pages_helper.rb +0 -12
  7. data/app/liquid/cms_paperclip_extension.rb +1 -1
  8. data/app/liquid/drops/cms_asset_drop.rb +15 -0
  9. data/app/liquid/filters/cms_filters.rb +1 -1
  10. data/app/liquid/tags/asset_search_tag.rb +26 -0
  11. data/app/liquid/tags/cms/tag_common.rb +29 -0
  12. data/app/liquid/tags/data_tag.rb +59 -0
  13. data/app/models/cms/asset.rb +109 -2
  14. data/app/models/cms/component.rb +21 -17
  15. data/app/models/cms/page.rb +1 -3
  16. data/app/models/cms/tag.rb +21 -0
  17. data/app/models/cms/taggable.rb +78 -0
  18. data/app/models/cms/tagging.rb +6 -0
  19. data/app/views/cms/assets/_asset.html.erb +2 -3
  20. data/app/views/cms/assets/_form.html.erb +53 -3
  21. data/app/views/cms/assets/_list.html.erb +16 -1
  22. data/app/views/cms/assets/_meta_field.html.erb +15 -0
  23. data/app/views/cms/documentation/_cms_drops.html.erb +18 -0
  24. data/app/views/cms/documentation/_cms_tags.html.erb +13 -0
  25. data/app/views/cms/pages/_page.html.erb +1 -3
  26. data/app/views/cms/shared/_sidebar.html.erb +30 -29
  27. data/generators/liquid_cms/lib/insert_commands.rb +14 -0
  28. data/generators/liquid_cms/liquid_cms_generator.rb +5 -1
  29. data/generators/liquid_cms/templates/config/initializers/cms/liquid_cms.rb +8 -0
  30. data/generators/liquid_cms/templates/config/locales/cms/en.yml +5 -0
  31. data/generators/liquid_cms/templates/migration_rev1.rb +38 -0
  32. data/generators/liquid_cms/templates/public/cms/stylesheets/sidebar.css +25 -7
  33. data/generators/liquid_cms/templates/public/cms/stylesheets/simple_form.css +79 -4
  34. data/generators/liquid_cms/templates/public/cms/stylesheets/styles.css +0 -8
  35. data/generators/liquid_cms/templates/public/cms/stylesheets/themes/dark.css +3 -0
  36. data/lib/liquid_cms/configuration.rb +12 -0
  37. data/lib/liquid_cms/version.rb +1 -1
  38. data/rails/init.rb +0 -1
  39. data/test/functional/assets_controller_test.rb +64 -16
  40. data/test/functional/components_controller_test.rb +90 -1
  41. data/test/functional/main_controller_test.rb +21 -0
  42. data/test/integration/pages_test.rb +124 -0
  43. data/test/integration/pages_test_no_context.rb +57 -0
  44. data/test/rails_app/db/migrate/20110329201435_create_liquid_cms_upgrade_rev1.rb +38 -0
  45. data/test/test_helper.rb +2 -0
  46. data/test/test_helpers/asset_helpers.rb +6 -4
  47. data/test/test_helpers/component_helpers.rb +35 -0
  48. data/test/test_helpers/file_helpers.rb +11 -0
  49. data/test/unit/asset_test.rb +114 -8
  50. data/test/unit/component_test.rb +65 -2
  51. data/test/unit/helpers/cms/common_helper_test.rb +4 -0
  52. metadata +35 -7
  53. data/app/views/cms/assets/destroy.js.rjs +0 -2
  54. data/generators/liquid_cms/templates/config/initializers/cms/vestal_versions.rb +0 -9
  55. data/test/rails_app/config/initializers/cms/vestal_versions.rb +0 -9
@@ -1,6 +1,11 @@
1
1
  require 'fileutils'
2
2
 
3
3
  Rails::Generator::Commands::Create.class_eval do
4
+ def delete(file)
5
+ logger.delete "Deleting '#{file}'"
6
+ FileUtils.rm_f file
7
+ end
8
+
4
9
  def copy_files(base, source, template_path = nil)
5
10
  logger.copy "Copying '#{source}' to '#{base}'"
6
11
  FileUtils.cp_r File.join(source_root, template_path || '', base, source), File.join(destination_root, base)
@@ -22,6 +27,11 @@ Rails::Generator::Commands::Create.class_eval do
22
27
  end
23
28
 
24
29
  Rails::Generator::Commands::Destroy.class_eval do
30
+ def delete(file)
31
+ logger.delete "Deleting '#{file}'"
32
+ FileUtils.rm_f file
33
+ end
34
+
25
35
  def copy_files(base, source)
26
36
  logger.copy "Removing '#{source}' from '#{base}'"
27
37
  FileUtils.rm_rf File.join(destination_root, base, source)
@@ -29,6 +39,10 @@ Rails::Generator::Commands::Destroy.class_eval do
29
39
  end
30
40
 
31
41
  Rails::Generator::Commands::List.class_eval do
42
+ def delete(file)
43
+ logger.delete "Deleting '#{file}'"
44
+ end
45
+
32
46
  def copy_files(base, source)
33
47
  logger.copy "Copying '#{source}' to '#{base}'"
34
48
  end
@@ -5,13 +5,17 @@ class LiquidCmsGenerator < Rails::Generator::Base
5
5
  record do |m|
6
6
  # migrations
7
7
  m.migration_template 'migration.rb', File.join('db', 'migrate'), :migration_file_name => 'create_liquid_cms_setup'
8
+ m.migration_template 'migration_rev1.rb', File.join('db', 'migrate'), :migration_file_name => 'create_liquid_cms_upgrade_rev1'
8
9
 
9
10
  # initializers
10
11
  m.directory File.join('config', 'initializers', 'cms')
11
- %w(liquid_cms.rb simple_form.rb simple_form_updates.rb vestal_versions.rb remote_indicator.rb).each do |file|
12
+ %w(liquid_cms.rb simple_form.rb simple_form_updates.rb remote_indicator.rb).each do |file|
12
13
  m.file File.join('config', 'initializers', 'cms', file), File.join('config', 'initializers', 'cms', file)
13
14
  end
14
15
 
16
+ # old files that need to be removed so that the app can run properly
17
+ m.delete File.join('config', 'initializers', 'cms', 'vestal_versions.rb')
18
+
15
19
  # cms controllers
16
20
  m.directory File.join('app', 'controllers', 'cms')
17
21
  m.file 'setup_controller.rb', File.join('app', 'controllers', 'cms', 'setup_controller.rb')
@@ -1,4 +1,12 @@
1
1
  Cms.setup do |config|
2
+ # Valid component file extensions that are allowed to be uploaded to the CMS.
3
+ # Defaults to %w(.css .js .png .jpg .jpeg .gif .json .xml .fla .ico .txt)
4
+ #config.valid_component_exts += %w(.xhtml .bmp)
5
+
6
+ # Compnent file types that can be edited (text based) in the CMS. Make sure new extensions here are also set in the valid_component_exts setting.
7
+ # Defaults to %w(.js .css .html .xml .txt)
8
+ #config.editable_component_exts += %w(.xhtml)
9
+
2
10
  # The class of your apps context object if it has one. This attribute must be set last.
3
11
  #config.context_class = :Context
4
12
  end
@@ -61,6 +61,7 @@ en:
61
61
  root: 'Home Page'
62
62
  cms_asset:
63
63
  asset_file_name: 'File'
64
+ tag_list: 'Tags'
64
65
  hints:
65
66
  cms_page:
66
67
  name: 'The name must contain no whitespace or any other special characters. Letters, numbers, hyphens, underscores and periods are valid.<br/>The extensions <em>.css</em>, <em>.js</em>, <em>.xml</em>, <em>.json</em> and <em>.txt</em> can used to auto-identify the content-type. If no extension is provided, html is the default type.'
@@ -71,6 +72,10 @@ en:
71
72
  file_content: '<em>No liquid support for editing components.</em> Use ctrl+s to save.'
72
73
  cms_asset:
73
74
  asset: 'Upload an asset file.'
75
+ tag_list: 'Seperate tags with commas.'
76
+ dimensions: 'Specify custom dimensions in pixels as width x height. The aspect ratio will be maintained, so actual dimensions may differ. Applies to image assets only.'
77
+ meta:
78
+ name: 'The name must begin with a letter and consist only of lowercase letters, numbers and underscores.'
74
79
  file_content: '<em>No liquid support for editing assets.</em> Use ctrl+s to save.'
75
80
  edit:
76
81
  asset: 'An existing file has been uploaded. Upload a new file to replace it.'
@@ -0,0 +1,38 @@
1
+ class CreateLiquidCmsUpgradeRev1 < ActiveRecord::Migration
2
+ def self.up
3
+ change_table :cms_assets do |t|
4
+ t.integer :custom_height
5
+ t.integer :custom_width
6
+ t.text :meta_data # serialized yaml
7
+ end
8
+
9
+ drop_table :versions
10
+
11
+ create_table :cms_tags do |t|
12
+ t.column :name, :string
13
+ end
14
+
15
+ create_table :cms_taggings do |t|
16
+ t.column :tag_id, :integer
17
+ t.column :taggable_id, :integer
18
+ t.column :taggable_type, :string
19
+
20
+ t.column :created_at, :datetime
21
+ end
22
+
23
+ add_index :cms_taggings, :tag_id
24
+ add_index :cms_taggings, [:taggable_id, :taggable_type]
25
+ end
26
+
27
+ def self.down
28
+ drop_table :cms_taggings
29
+ drop_table :cms_tags
30
+
31
+ create_table :versions do |t|
32
+ end
33
+
34
+ change_table :cms_assets do |t|
35
+ t.remove :custom_height, :custom_width, :meta_data
36
+ end
37
+ end
38
+ end
@@ -19,15 +19,35 @@
19
19
  margin: 0;
20
20
  padding: 0;
21
21
  }
22
- #sidebar #assets li {
22
+ #sidebar #assets li.cms_asset {
23
+ position: relative;
24
+ }
25
+ #sidebar #assets li.group.tagged {
26
+ margin-bottom: 0.5em;
27
+ }
28
+ #sidebar #assets li.group li {
23
29
  border: 1px solid #AAA;
24
30
  padding: 0.3em 0.4em;
25
31
  margin-bottom: 0.3em;
26
32
  }
27
- #sidebar #assets li:hover {
33
+ #sidebar #assets li.group h4 {
34
+ background-color: #BBB;
35
+ border: 1px solid #999;
36
+ margin: 0.2em 0;
37
+ padding: 0.4em;
38
+ text-shadow: -1px -1px 1px #CCCCCC;
39
+ }
40
+ #sidebar #assets li.group.tagged h4 {
41
+ background: url("/cms/images/icons/tag_blue.png") no-repeat scroll 5px center #BBB;
42
+ padding: 0.4em 0.4em 0.4em 25px;
43
+ }
44
+ #sidebar #assets li.group h4 a {
45
+ float: right;
46
+ }
47
+ #sidebar #assets li.group li:hover {
28
48
  background-color: #BFD6FF !important;
29
49
  }
30
- #sidebar #assets li.light {
50
+ #sidebar #assets li.group li.light {
31
51
  background-color: #DDD;
32
52
  }
33
53
  #sidebar .asset_details {
@@ -41,7 +61,8 @@
41
61
  }
42
62
  #sidebar .asset_size {
43
63
  font-size: 8pt;
44
- float: right;
64
+ position: absolute;
65
+ right: 0.4em;
45
66
  }
46
67
  #sidebar #components form {
47
68
  margin-bottom: 0.5em;
@@ -120,9 +141,6 @@
120
141
  #cms ul.tree li { margin: 0; padding: 0 0px 0 12px; line-height: 20px; background: url(/cms/images/tree/node.png) no-repeat; color: #369; font-weight: bold; }
121
142
  #cms ul.tree li:last-child { background: url(/cms/images/tree/lastnode.png) no-repeat; }
122
143
 
123
- #cms ul.tree, #sidebar #assets ul {
124
- margin-bottom: 0.5em;
125
- }
126
144
  #cms ul.tree ul {
127
145
  margin-left: 15px;
128
146
  }
@@ -43,17 +43,18 @@ form.simple_form a.cancel:hover {
43
43
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0,#F55), color-stop(1.0,#C11));
44
44
  }
45
45
 
46
- form.simple_form div.string, form.simple_form div.text, form.simple_form div.boolean, form.simple_form div.select, form.simple_form div.file {
46
+ form.simple_form div.string, form.simple_form div.text, form.simple_form div.boolean, form.simple_form div.select, form.simple_form div.file, form.simple_form div.integer {
47
47
  margin-bottom: 1.3em;
48
48
  }
49
- form.simple_form label {
50
- color: #333;
49
+ form.simple_form label, form.simple_form .label {
51
50
  float: left;
51
+ width: 9%;
52
+ color: #333;
52
53
  font-size: 10pt;
53
54
  font-family: Verdana;
54
55
  font-weight: bold;
55
56
  line-height: 1.8em;
56
- width: 9%;
57
+ text-shadow: 1px 1px 1px #DDD;
57
58
  }
58
59
  form.simple_form input.string {
59
60
  display: block;
@@ -66,6 +67,13 @@ form.simple_form .buttons { margin-left: 9%; margin-top: 1.5em; }
66
67
  form.simple_form span.hint { color: #666; display: block; font-size: 8pt; font-style: italic; margin: 0.5em 0 0 9%;}
67
68
  form.simple_form span.hint em { color: #333; font-weight: bold; }
68
69
 
70
+ form.simple_form div.fieldWithErrors:first-child {
71
+ width: 9%;
72
+ float: left;
73
+ }
74
+ form.simple_form div.fieldWithErrors:first-child label {
75
+ float: none;
76
+ }
69
77
  form.simple_form div.fieldWithErrors { background-color: #FBE3E4; padding: 0.5em 0; }
70
78
  form.simple_form span.error {
71
79
  background: white;
@@ -77,3 +85,70 @@ form.simple_form span.error {
77
85
  margin-top: 0.5em;
78
86
  padding: 0.5em;
79
87
  }
88
+
89
+ form.simple_form .preview {
90
+ margin-bottom: 1em;
91
+ }
92
+ form.simple_form .preview h4 {
93
+ margin-top: 0;
94
+ margin-bottom: 0.5em;
95
+ }
96
+ form.simple_form .preview img {
97
+ border: 1px solid #CCC;
98
+ }
99
+ form.simple_form .details p:first-child {
100
+ margin-top: 0;
101
+ }
102
+ form.simple_form .details .label {
103
+ display: inline-block;
104
+ float: none;
105
+ }
106
+
107
+ .CodeMirror-wrapping {
108
+ display: inline-block;
109
+ }
110
+ .CodeMirror-wrapping iframe {
111
+ background-color: white;
112
+ border: 1px solid #BBBBBB !important;
113
+ }
114
+
115
+ div.dimensions {
116
+ margin-bottom: 1.3em;
117
+ }
118
+ div.dimensions div.integer {
119
+ display: inline;
120
+ }
121
+
122
+ fieldset legend {
123
+ font-weight: bold;
124
+ text-shadow: 1px 1px 1px #DDD;
125
+ }
126
+ ul#meta_fields {
127
+ list-style-type: none;
128
+ padding-left: 0;
129
+ margin: 0.5em 0 0;
130
+ }
131
+ ul#meta_fields li {
132
+ position: relative;
133
+ background: #EEE;
134
+ background: -moz-linear-gradient(0deg, #EEEEEE 0%, #F3F3F3 100%) repeat scroll 0 0 transparent;
135
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0,#EEE), color-stop(1.0,#F3F3F3));
136
+ border: 1px solid #999;
137
+ margin-bottom: 0.5em;
138
+ padding: 0.5em;
139
+ padding-bottom: 0;
140
+ }
141
+ ul#meta_fields li div.field {
142
+ margin-top: 0.5em;
143
+ }
144
+ ul#meta_fields li div.field input.string {
145
+ width: auto;
146
+ }
147
+ ul#meta_fields li .delete {
148
+ position: absolute;
149
+ bottom: 0.5em;
150
+ right: 0.5em;
151
+ }
152
+ form.simple_form ul div.string, form.simple_form ul div.text {
153
+ margin-bottom: 0.5em;
154
+ }
@@ -105,14 +105,6 @@ h2 p.message {
105
105
  float: right;
106
106
  }
107
107
 
108
- .CodeMirror-wrapping {
109
- display: inline-block;
110
- }
111
- .CodeMirror-wrapping iframe {
112
- background-color: white;
113
- border: 1px solid #BBBBBB !important;
114
- }
115
-
116
108
  .cms_pages #content h2 {
117
109
  background: url("/cms/images/icons/page.png") no-repeat scroll right 50% transparent;
118
110
  }
@@ -13,6 +13,9 @@ body {
13
13
  #content a {
14
14
  color: #FFE900;
15
15
  }
16
+ #content form.simple_form a {
17
+ color: #170;
18
+ }
16
19
  #content h2 {
17
20
  color: #AAA;
18
21
  text-shadow: -1px -1px 2px #000000;
@@ -29,6 +29,18 @@ module Cms
29
29
  route_map.connect '*url', :controller => 'cms/pages', :action => 'load'
30
30
  end
31
31
 
32
+ mattr_reader :valid_component_exts
33
+ def self.valid_component_exts=(exts)
34
+ @@valid_component_exts = exts.to_a
35
+ end
36
+ @@valid_component_exts = %w(.css .js .png .jpg .jpeg .gif .json .xml .fla .ico .txt)
37
+
38
+ mattr_reader :editable_component_exts
39
+ def self.editable_component_exts=(exts)
40
+ @@editable_component_exts = exts.to_a
41
+ end
42
+ @@editable_component_exts = %w(.js .css .html .xml .txt)
43
+
32
44
  def self.setup
33
45
  yield self
34
46
  end
@@ -1,3 +1,3 @@
1
1
  module Cms
2
- VERSION = "0.2.0.13"
2
+ VERSION = "0.2.1.0"
3
3
  end
data/rails/init.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'liquid_cms'
2
- require 'vestal_versions'
3
2
  require 'simple_form'
4
3
  require 'zip/zip'
5
4
  require 'will_paginate'
@@ -13,6 +13,53 @@ class Cms::AssetsControllerTest < ActionController::TestCase
13
13
  assert_select 'div.text', false
14
14
  assert_select 'div.file .hint', 'Upload an asset file.'
15
15
  end
16
+
17
+ should "populate the new asset with tag and meta details" do
18
+ asset = Factory(:image_asset, :context => @company, :tag_list => 'test', :meta_data => [{:name => 'field1', :value => 'test1'}, {:name => 'field2', :value => 'test2'}], :custom_width => 200, :custom_height => 100)
19
+ get :new, :tag => asset.tag_list.to_s
20
+ assert_response :success
21
+
22
+ new_asset = assigns(:asset)
23
+ assert_equal 'test', new_asset.tag_list.to_s
24
+ assert_equal 2, new_asset.meta_data.length
25
+ # values are removed from new assets
26
+ assert_equal 'field1', new_asset.meta_data[0][:name]
27
+ assert_equal '', new_asset.meta_data[0][:value]
28
+ assert_equal 'field2', new_asset.meta_data[1][:name]
29
+ assert_equal '', new_asset.meta_data[1][:value]
30
+ assert_equal 200, new_asset.custom_width
31
+ assert_equal 100, new_asset.custom_height
32
+
33
+ assert_select '#meta_fields li', new_asset.meta_data.length
34
+ end
35
+
36
+ should "not populate the new asset with tag and meta details" do
37
+ asset = Factory(:image_asset, :context => @company, :tag_list => 'test', :meta_data => [{:name => 'field1', :value => 'test1'}, {:name => 'field2', :value => 'test2'}])
38
+ get :new, :tag => 'unknown'
39
+ assert_response :success
40
+
41
+ new_asset = assigns(:asset)
42
+ assert_equal 'unknown', new_asset.tag_list.to_s
43
+ assert_nil new_asset.meta_data
44
+ end
45
+ end
46
+
47
+ context "create" do
48
+ teardown do
49
+ cleanup_assets
50
+ end
51
+
52
+ should "create an asset" do
53
+ asset_file = asset_file('new_test.pdf')
54
+ setup_asset asset_file
55
+
56
+ post :create, :cms_asset => {:asset => ActionController::TestUploadedFile.new(asset_file), :meta => {'new_0' => {:name => 'key_a', :value => 'test'}, 'new_1' => {:name => 'key_b', :value => 'test'}} }
57
+ assert_response :redirect
58
+ assert_redirected_to cms_root_path
59
+
60
+ asset = assigns(:asset)
61
+ assert_equal 2, asset.meta_data.length
62
+ end
16
63
  end
17
64
 
18
65
  context "show" do
@@ -39,7 +86,7 @@ class Cms::AssetsControllerTest < ActionController::TestCase
39
86
 
40
87
  context "edit" do
41
88
  should "show form for an editable asset with a textarea" do
42
- Cms::Asset.any_instance.stubs(:asset).returns(stub(:to_file => stub(:read => 'test contents')))
89
+ Cms::Asset.any_instance.stubs(:asset).returns(stub(:url => 'test.com', :to_file => stub(:read => 'test contents')))
43
90
  asset = Factory(:js_asset, :context => @company)
44
91
 
45
92
  get :edit, :id => asset.id
@@ -78,24 +125,33 @@ class Cms::AssetsControllerTest < ActionController::TestCase
78
125
  assert_equal File.basename(new_asset_file), asset.reload.asset_file_name
79
126
  end
80
127
 
81
- should "modify the contents of an editable asset file" do
128
+ should "modify the contents of a non-editable asset file" do
82
129
  asset = Factory(:pdf_asset, :context => @company)
83
- put :update, :id => asset, :file_content => 'new content'
84
- assert_response :success
85
- assert_template 'edit'
130
+
131
+ # file contents are ignored for non-editable assets
132
+ put :update, :id => asset, :cms_asset => {:file_content => 'new content'}
133
+ assert_response :redirect
134
+ assert_redirected_to cms_root_path
86
135
  end
87
136
 
88
- should "modify the contents of an non-editable asset file" do
137
+ should "modify the contents of an editable asset file and it's meta data" do
89
138
  asset = Factory(:js_asset, :context => @company)
139
+ assert_nil asset.meta_data
140
+ assert_equal 0, asset.meta.length
90
141
 
91
142
  asset_file = asset_file(asset.asset_file_name)
92
143
  setup_asset asset_file
93
144
 
94
145
  Cms::Asset.any_instance.stubs(:asset => stub(:path => asset_file))
95
- Cms::Asset.any_instance.expects(:write).with('new content').returns(true)
146
+ Cms::Asset.any_instance.expects(:file_content=).with('new content').returns('new content')
96
147
 
97
- put :update, :id => asset, :file_content => 'new content'
148
+ put :update, :id => asset, :cms_asset => {:file_content => 'new content', :meta => {'new_0' => {:name => 'key_a', :value => 'test'}, 'new_1' => {:name => 'key_b', :value => 'test'}}}
98
149
  assert_response :redirect
150
+ assert_redirected_to cms_root_path
151
+
152
+ asset.reload
153
+ assert_not_nil asset.meta_data
154
+ assert_equal 2, asset.meta.length
99
155
  end
100
156
  end
101
157
 
@@ -112,14 +168,6 @@ class Cms::AssetsControllerTest < ActionController::TestCase
112
168
  assert_redirected_to cms_root_path
113
169
  assert_nil @company.assets.find_by_id(@asset.id)
114
170
  end
115
-
116
- should "destroy asset via XHR :DELETE" do
117
- assert_not_nil @company.assets.find_by_id(@asset.id)
118
-
119
- xhr :delete, :destroy, :id => @asset
120
- assert_response :success
121
- assert_nil @company.assets.find_by_id(@asset.id)
122
- end
123
171
  end
124
172
  end
125
173
  end