liquid_cms 0.3.0.9 → 0.3.0.10

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,9 @@
1
+ == 0.3.0.10
2
+
3
+ * Enhancements
4
+ * Integrate basic page search capabilities.
5
+ * locale file now allows you to change the CMS title
6
+
1
7
  == 0.3.0.9
2
8
 
3
9
  * Enhancements
@@ -17,8 +17,8 @@ protected
17
17
  def load_resources
18
18
  @context = Cms::Context.new(@cms_context)
19
19
 
20
- @pages = @context.pages.ordered.all(:conditions => {:layout_page_id => nil})
21
- @assets = @context.assets.ordered
22
- @components = @context.components
20
+ @cms_pages = @context.pages.ordered.all(:conditions => {:layout_page_id => nil})
21
+ @cms_assets = @context.assets.ordered
22
+ @cms_components = @context.components
23
23
  end
24
24
  end
@@ -3,6 +3,8 @@ class Cms::PagesController < Cms::MainController
3
3
 
4
4
  authenticate_user :all, :except => %w(load page_asset)
5
5
 
6
+ SEARCH_LIMIT = 40
7
+
6
8
  def new
7
9
  @page = Cms::Page.new
8
10
  end
@@ -88,7 +90,15 @@ class Cms::PagesController < Cms::MainController
88
90
  end
89
91
  end
90
92
 
93
+ def search
94
+ @search_term = (params[:search] || '').strip
95
+ # use upper which should be compatible with mysql, postgresql and sqlite
96
+ @pages = @search_term.blank? ? [] : @context.pages.all(:conditions => ["upper(content) like ?", "%#{@search_term.upcase}%"])
97
+ end
98
+
91
99
  protected
100
+ # the current url with the last level of the path removed which essentially allows a page to be loaded with anything (wildcard) one level deeper
101
+ # ex. normal page at /page will also accept /page/test, /page/abcd, etc.
92
102
  def wildcard_path
93
103
  '/'+params[:url].split('/').slice(0..-2).join('/')
94
104
  end
@@ -14,4 +14,10 @@ module Cms::PagesHelper
14
14
  link_to cms_icon('delete.png', :title => 'Delete'), cms_page_path(page), options
15
15
  end
16
16
  end
17
+
18
+ # find the # of term matches in each page and sorts the pages by the match count (highest to lowest)
19
+ # only shows the first SEARCH_LIMIT pages
20
+ def page_match_order(pages, term)
21
+ pages.collect{|page| [page, page.content.scan(/#{term}/i).length]}.sort{|a,b| b[1] <=> a[1]}[0..(Cms::PagesController::SEARCH_LIMIT-1)]
22
+ end
17
23
  end
@@ -1,14 +1,17 @@
1
1
  <div id="assets">
2
2
  <p>
3
- <%= cms_icon 'picture_add.png' %> <%= link_to t('assets.actions.index.new_link'), new_cms_asset_path %>
3
+ <%= cms_icon 'picture_add.png' %> <%= link_to t('assets.actions.index.new'), new_cms_asset_path %>
4
4
  </p>
5
5
 
6
- <% if @assets.empty? %>
6
+ <% if @cms_assets.empty? %>
7
7
  <p><%= t 'assets.actions.index.none' %></p>
8
8
  <% else %>
9
+ <% if @cms_assets.any?(&:image?) %>
9
10
  <p class="preview"><%= link_to_function 'Toggle image previews', "asset_preview_toggle()" %></p>
11
+ <% end %>
12
+
10
13
  <ul>
11
- <%= render :partial => 'cms/assets/asset', :collection => @assets %>
14
+ <%= render :partial => 'cms/assets/asset', :collection => @cms_assets %>
12
15
  </ul>
13
16
  <% end %>
14
17
  </div>
@@ -1,14 +1,12 @@
1
- <div class="basic">
2
- <h2><%= @asset.asset_file_name %></h2>
1
+ <h2><%= @asset.asset_file_name %></h2>
3
2
 
4
- <% if @asset.image? %>
5
- <%= image_tag @asset.asset.url %>
6
- <% else %>
7
- <p>Open: <%= link_to @asset.asset_file_name, @asset.asset.url %></p>
8
- <% end %>
3
+ <% if @asset.image? %>
4
+ <%= image_tag @asset.asset.url %>
5
+ <% else %>
6
+ <p>Open: <%= link_to @asset.asset_file_name, @asset.asset.url %></p>
7
+ <% end %>
9
8
 
10
- <p>Filesize: <%= number_to_human_size(@asset.asset_file_size) %></p>
11
- <p>Last Updated: <%= @asset.asset_updated_at.to_formatted_s(:long) %></p>
9
+ <p>Filesize: <%= number_to_human_size(@asset.asset_file_size) %></p>
10
+ <p>Last Updated: <%= @asset.asset_updated_at.to_formatted_s(:long) %></p>
12
11
 
13
- <p><%= link_to 'Edit Asset', edit_cms_asset_path(@asset) %></p>
14
- </div>
12
+ <p><%= link_to 'Edit Asset', edit_cms_asset_path(@asset) %></p>
@@ -1,12 +1,14 @@
1
1
  <div id="components">
2
2
  <%= form_tag cms_components_upload_path, :multipart => true do %>
3
- <%= file_field_tag :zip_file %>
4
- <%= submit_tag 'Upload' %> <em>.zip files only</em>
3
+ <div>
4
+ <%= file_field_tag :zip_file %>
5
+ <%= submit_tag 'Upload' %> <em>.zip files only</em>
6
+ </div>
5
7
  <% end %>
6
8
 
7
- <% if @components.empty? %>
9
+ <% if @cms_components.empty? %>
8
10
  <p><%= t 'components.actions.index.none' %></p>
9
11
  <% else %>
10
- <%= list_files @components %>
12
+ <%= list_files @cms_components %>
11
13
  <% end %>
12
14
  </div>
@@ -1,13 +1,13 @@
1
1
  <div id="pages">
2
- <p>
3
- <%= cms_icon 'page_add.png' %> <%= link_to t('pages.actions.index.new_link'), new_cms_page_path %>
4
- </p>
2
+ <p><%= cms_icon 'page_add.png' %> <%= link_to t('pages.actions.index.new'), new_cms_page_path %></p>
5
3
 
6
- <% if @pages.empty? %>
4
+ <% if @cms_pages.empty? %>
7
5
  <p><%= t 'pages.actions.index.none' %></p>
8
6
  <% else %>
7
+ <p><%= cms_icon 'page_find.png' %> <%= link_to t('pages.actions.index.search'), search_cms_pages_path %></p>
8
+
9
9
  <ul class="tree">
10
- <%= render :partial => 'cms/pages/page', :collection => @pages %>
10
+ <%= render :partial => 'cms/pages/page', :collection => @cms_pages %>
11
11
  </ul>
12
12
  <% end %>
13
13
  </div>
@@ -0,0 +1,24 @@
1
+ <h2><%= t 'pages.actions.search.title' %></h2>
2
+
3
+ <%= form_tag search_cms_pages_path, {:class => 'simple_form'} do %>
4
+ <%= text_field_tag 'search', @search_term, :size => 45, :placeholder => 'enter your search term' %>
5
+ <%= submit_tag 'Search' %>
6
+ <% end %>
7
+
8
+ <div id="search_results">
9
+ <% if @pages.empty? && request.post? %>
10
+ <p>No matching pages were found.</p>
11
+ <% elsif !@pages.empty? %>
12
+ <% if @pages.length >= Cms::PagesController::SEARCH_LIMIT %>
13
+ <p>Search results have been limited to <%= Cms::PagesController::SEARCH_LIMIT %> pages. &nbsp;Use a more exact search term to refine your results.</p>
14
+ <% else %>
15
+ <p><%= pluralize @pages.length, 'page' %> found.</p>
16
+ <% end %>
17
+
18
+ <ul class="panel shadow">
19
+ <% for page, matches in page_match_order(@pages, @search_term) %>
20
+ <li><span class="page"><%= link_to page.to_s, edit_cms_page_path(page) %></span> - <span class="count"><%= pluralize matches, 'match' %></span></li>
21
+ <% end %>
22
+ </ul>
23
+ <% end %>
24
+ </div>
@@ -1,3 +1,3 @@
1
- <div id="intro" class="shadow curved">
1
+ <div id="intro" class="panel shadow curved">
2
2
  <p>Add a new page or upload a new asset.</p>
3
3
  </div>
@@ -3,7 +3,7 @@
3
3
  <html xmlns="http://www.w3.org/1999/xhtml">
4
4
  <head>
5
5
  <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
6
- <title>Liquid CMS</title>
6
+ <title><%= t 'pages.layout.title' %></title>
7
7
  <%= javascript_include_tag 'prototype', 'effects', 'rails' %>
8
8
  <%= javascript_include_tag '/cms/javascripts/humanmsg', '/cms/javascripts/cookiejar', '/cms/javascripts/remote_helpers', '/cms/javascripts/cms', '/cms/javascripts/livepipe', '/cms/javascripts/tabs', :cache => 'cms_scripts' %>
9
9
  <%= javascript_include_tag '/cms/codemirror/js/codemirror' %>
@@ -19,9 +19,9 @@
19
19
  <![endif]-->
20
20
  <%= csrf_meta_tag %>
21
21
  </head>
22
- <body id="cms" class="cms_<%= params[:controller].camelize.demodulize.downcase %>">
22
+ <body id="cms" class="cms_<%= params[:controller].camelize.demodulize.downcase %> cms_action_<%= params[:action].camelize.demodulize.downcase %>">
23
23
  <div id="header">
24
- <h1><%= link_to 'Liquid CMS', cms_root_path %></h1>
24
+ <h1><%= link_to t('pages.layout.title'), cms_root_path %></h1>
25
25
  </div>
26
26
 
27
27
  <div id="outer-container" class="clearfix">
@@ -1,14 +1,19 @@
1
1
  en:
2
2
  pages:
3
+ layout:
4
+ title: 'Liquid CMS'
3
5
  actions:
4
6
  index:
5
7
  title: 'Pages'
6
8
  none: 'There are currently no pages.'
7
- new_link: 'Create a new page'
9
+ new: 'Create a new page'
10
+ search: 'Search'
8
11
  new:
9
12
  title: 'New Page'
10
13
  edit:
11
14
  title: 'Editing Page'
15
+ search:
16
+ title: 'Page Search'
12
17
  flash:
13
18
  created: 'The page has been saved.'
14
19
  updated: 'The page has been updated.'
@@ -19,7 +24,7 @@ en:
19
24
  index:
20
25
  title: 'Assets'
21
26
  none: 'There are currently no assets.'
22
- new_link: 'Upload a new asset'
27
+ new: 'Upload a new asset'
23
28
  new:
24
29
  title: 'New Asset'
25
30
  edit:
data/config/routes.rb CHANGED
@@ -7,7 +7,11 @@ Rails.application.routes.draw do
7
7
  end
8
8
 
9
9
  resources :assets, :except => :index
10
- resources :pages, :except => [:index, :show]
10
+ resources :pages, :except => [:index, :show] do
11
+ collection do
12
+ match :search, :via => [:get, :post]
13
+ end
14
+ end
11
15
  resources :documentation, :only => :index
12
16
  match ':path/:id.:format', :to => 'pages#page_asset', :requirements => {:path => /javascripts|stylesheets/}
13
17
 
@@ -4,12 +4,6 @@ h4 {
4
4
  .cms_documentation #content h2 {
5
5
  margin-top: 1em;
6
6
  }
7
- .cms_documentation #content a {
8
- text-decoration: none;
9
- }
10
- .cms_documentation #content a:hover {
11
- text-decoration: underline;
12
- }
13
7
  #content pre {
14
8
  margin: 0;
15
9
  }
@@ -25,6 +19,7 @@ span.function {
25
19
  }
26
20
  .required {
27
21
  background-color: #FFF15F;
22
+ padding: 0 2px;
28
23
  }
29
24
  .example {
30
25
  font-style: italic;
@@ -32,10 +32,10 @@ form.simple_form a.cancel {
32
32
  background: #D00;
33
33
  background: -moz-linear-gradient(90deg, #BB0000 0%, #EE4444 100%) repeat scroll 0 0 transparent;
34
34
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0,#E44), color-stop(1.0,#B00));
35
- color: white;
35
+ color: white !important;
36
36
  margin-left: 0.3em;
37
37
  text-decoration: none;
38
- text-shadow: 0 1px #555;
38
+ text-shadow: 0px 1px 0px #555;
39
39
  }
40
40
  form.simple_form a.cancel:hover {
41
41
  background: #E00;
@@ -55,10 +55,15 @@ a img {
55
55
  }
56
56
 
57
57
  #content {
58
+ color: #333333;
59
+ min-width: 500px;
58
60
  margin-left: 23em;
59
61
  margin-right: 1em;
60
62
  padding-bottom: 0.5em;
61
63
  }
64
+ #content .panel, #content form {
65
+ color: #333;
66
+ }
62
67
  #content h1 {
63
68
  padding-top: 0.5em;
64
69
  margin-top: 0;
@@ -72,7 +77,6 @@ a img {
72
77
  padding: 0.5em;
73
78
  text-align: center;
74
79
  background: none repeat scroll 0 0 #CCCCCC;
75
- color: #333333;
76
80
  font-weight: bold;
77
81
  line-height: 5em;
78
82
  padding: 0.5em;
@@ -112,6 +116,45 @@ h2 p.message {
112
116
  .cms_pages #content h2 {
113
117
  background: url("/cms/images/icons/page.png") no-repeat scroll right 50% transparent;
114
118
  }
119
+ .cms_pages.cms_action_search #content h2 {
120
+ background: url("/cms/images/icons/page_find.png") no-repeat scroll right 50% transparent;
121
+ }
115
122
  .cms_assets #content h2 {
116
123
  background: url("/cms/images/icons/picture.png") no-repeat scroll right 50% transparent;
117
124
  }
125
+
126
+ #search_results p {
127
+ font-weight: bold;
128
+ }
129
+ #search_results ul {
130
+ border: 1px solid #CCC;
131
+ list-style-type: none;
132
+ margin: 0;
133
+ padding: 0;
134
+ }
135
+ #search_results li {
136
+ line-height: 2em;
137
+ padding: 0.2em 0.5em;
138
+ margin-bottom: 1px;
139
+ }
140
+ #search_results li:last-child {
141
+ margin-bottom: 0;
142
+ }
143
+ #search_results li a {
144
+ color: black;
145
+ font-weight: bold;
146
+ }
147
+ #search_results li:nth-child(odd) {
148
+ background-color: #F5F5F5;
149
+ }
150
+ #search_results li:nth-child(even) {
151
+ background-color: lightGoldenRodYellow;
152
+ }
153
+ #search_results li:hover {
154
+ background-color: #BFD6FF !important;
155
+ }
156
+ #search_results li .page {
157
+ }
158
+ #search_results li .count {
159
+ font-family: courier new;
160
+ }
@@ -5,23 +5,24 @@ body {
5
5
  background: #222;
6
6
  background: -moz-linear-gradient(270deg, #555555 0%, #222 40%, #000 100%) repeat scroll 0 0 transparent;
7
7
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0,#555), color-stop(0.40,#222), color-stop(1.0,#000));
8
+ color: #EEE;
8
9
  }
9
- #content h2 {
10
- color: #AAA;
11
- text-shadow: -1px -1px 2px #000000;
12
- }
13
- .cms_documentation #content {
10
+ #content {
14
11
  color: #EEE;
15
12
  }
16
- #content .basic a, .cms_documentation #content a {
13
+ #content a {
17
14
  color: #FFE900;
18
15
  }
19
- #content .basic p, .cms_components #content p {
20
- color: white;
16
+ #content h2 {
17
+ color: #AAA;
18
+ text-shadow: -1px -1px 2px #000000;
21
19
  }
22
20
  .cms_documentation span.function {
23
21
  color: #49FF3F;
24
22
  }
23
+ .cms_documentation .required {
24
+ color: #333;
25
+ }
25
26
  .cms_documentation .cms_info {
26
27
  color: #333;
27
28
  }
@@ -1,3 +1,3 @@
1
1
  module Cms
2
- VERSION = "0.3.0.9"
2
+ VERSION = "0.3.0.10"
3
3
  end
@@ -13,11 +13,20 @@ class Cms::MainControllerTest < ActionController::TestCase
13
13
 
14
14
  get :index
15
15
  assert_response :success
16
+ assert_select "#assets p.preview", true
16
17
  assert_select "li#cms_asset_#{img_asset.id} a", img_asset.asset_file_name
17
18
  assert_select "li#cms_asset_#{img_asset.id} div.asset_image"
18
19
  assert_select "li#cms_asset_#{pdf_asset.id} a", pdf_asset.asset_file_name
19
20
  assert_select "li#cms_asset_#{pdf_asset.id} div.asset_image", false
20
21
  end
22
+
23
+ should "not should the preview link if no images have been uploaded" do
24
+ pdf_asset = Factory(:pdf_asset, :context => @company)
25
+
26
+ get :index
27
+ assert_response :success
28
+ assert_select "#assets p.preview", false
29
+ end
21
30
  end
22
31
 
23
32
  context "permission access" do
@@ -88,5 +88,50 @@ class Cms::PagesControllerTest < ActionController::TestCase
88
88
  xhr :delete, :destroy, :id => @company.pages.first.id
89
89
  assert_response :success
90
90
  end
91
+
92
+ context "search" do
93
+ setup do
94
+ # the company already has a home page created
95
+ @page1 = @company.pages.first
96
+ # so we'll create a second page
97
+ @page2 = Factory.create :page, :context => @company, :content => 'add search keywords - page page page'
98
+ end
99
+
100
+ should "show no results via :GET" do
101
+ get :search
102
+ assert_response :success
103
+ assert_select '#content form'
104
+ assert_select '#search_results p', false
105
+ assert_select '#search_results ul', false
106
+ end
107
+
108
+ should "show a message with an empty search via :POST" do
109
+ post :search, :search => ''
110
+ assert_response :success
111
+ assert_select '#content form'
112
+ assert_select '#search_results p', 'No matching pages were found.'
113
+ assert_select '#search_results ul', false
114
+ end
115
+
116
+ should "show results via :POST" do
117
+ post :search, :search => 'page'
118
+ assert_response :success
119
+ assert_select '#search_results p', '2 pages found.'
120
+ assert_select '#search_results ul', true
121
+ assert_select '#search_results li', 2
122
+ assert_select '#search_results li', "#{@page2} - 3 matches"
123
+ assert_select '#search_results li', "#{@page1} - 1 match"
124
+ end
125
+
126
+ should "show search limit" do
127
+ (1..40).each do |i|
128
+ Factory.create :page, :context => @company, :name => "test#{i}", :slug => "/test#{i}", :content => 'page'
129
+ end
130
+
131
+ post :search, :search => 'page'
132
+ assert_response :success
133
+ assert_select '#search_results p', 'Search results have been limited to 40 pages. &nbsp;Use a more exact search term to refine your results.'
134
+ end
135
+ end
91
136
  end
92
137
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: liquid_cms
3
3
  version: !ruby/object:Gem::Version
4
- hash: 69
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
7
  - 3
9
8
  - 0
10
- - 9
11
- version: 0.3.0.9
9
+ - 10
10
+ version: 0.3.0.10
12
11
  platform: ruby
13
12
  authors:
14
13
  - Andrew Kaspick
@@ -17,7 +16,7 @@ autorequire:
17
16
  bindir: bin
18
17
  cert_chain: []
19
18
 
20
- date: 2011-03-03 00:00:00 -06:00
19
+ date: 2011-03-09 00:00:00 -06:00
21
20
  default_executable:
22
21
  dependencies:
23
22
  - !ruby/object:Gem::Dependency
@@ -28,7 +27,6 @@ dependencies:
28
27
  requirements:
29
28
  - - ">="
30
29
  - !ruby/object:Gem::Version
31
- hash: 23
32
30
  segments:
33
31
  - 1
34
32
  - 0
@@ -44,7 +42,6 @@ dependencies:
44
42
  requirements:
45
43
  - - ~>
46
44
  - !ruby/object:Gem::Version
47
- hash: 7
48
45
  segments:
49
46
  - 3
50
47
  - 0
@@ -60,7 +57,6 @@ dependencies:
60
57
  requirements:
61
58
  - - ~>
62
59
  - !ruby/object:Gem::Version
63
- hash: 1
64
60
  segments:
65
61
  - 2
66
62
  - 3
@@ -76,7 +72,6 @@ dependencies:
76
72
  requirements:
77
73
  - - ~>
78
74
  - !ruby/object:Gem::Version
79
- hash: 31
80
75
  segments:
81
76
  - 1
82
77
  - 2
@@ -92,7 +87,6 @@ dependencies:
92
87
  requirements:
93
88
  - - ~>
94
89
  - !ruby/object:Gem::Version
95
- hash: 57
96
90
  segments:
97
91
  - 0
98
92
  - 9
@@ -108,7 +102,6 @@ dependencies:
108
102
  requirements:
109
103
  - - ~>
110
104
  - !ruby/object:Gem::Version
111
- hash: 27
112
105
  segments:
113
106
  - 2
114
107
  - 3
@@ -124,7 +117,6 @@ dependencies:
124
117
  requirements:
125
118
  - - ">="
126
119
  - !ruby/object:Gem::Version
127
- hash: 3
128
120
  segments:
129
121
  - 0
130
122
  version: "0"
@@ -138,7 +130,6 @@ dependencies:
138
130
  requirements:
139
131
  - - ">="
140
132
  - !ruby/object:Gem::Version
141
- hash: 3
142
133
  segments:
143
134
  - 0
144
135
  version: "0"
@@ -152,7 +143,6 @@ dependencies:
152
143
  requirements:
153
144
  - - ~>
154
145
  - !ruby/object:Gem::Version
155
- hash: 27
156
146
  segments:
157
147
  - 1
158
148
  - 3
@@ -168,7 +158,6 @@ dependencies:
168
158
  requirements:
169
159
  - - ~>
170
160
  - !ruby/object:Gem::Version
171
- hash: 33
172
161
  segments:
173
162
  - 2
174
163
  - 10
@@ -184,7 +173,6 @@ dependencies:
184
173
  requirements:
185
174
  - - ">="
186
175
  - !ruby/object:Gem::Version
187
- hash: 3
188
176
  segments:
189
177
  - 0
190
178
  version: "0"
@@ -256,6 +244,7 @@ files:
256
244
  - app/views/cms/pages/destroy.js.rjs
257
245
  - app/views/cms/pages/edit.html.erb
258
246
  - app/views/cms/pages/new.html.erb
247
+ - app/views/cms/pages/search.html.erb
259
248
  - app/views/cms/shared/_index.html.erb
260
249
  - app/views/cms/shared/_sidebar.html.erb
261
250
  - app/views/layouts/cms.html.erb
@@ -1504,7 +1493,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
1504
1493
  requirements:
1505
1494
  - - ">="
1506
1495
  - !ruby/object:Gem::Version
1507
- hash: 3
1508
1496
  segments:
1509
1497
  - 0
1510
1498
  version: "0"
@@ -1513,7 +1501,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1513
1501
  requirements:
1514
1502
  - - ">="
1515
1503
  - !ruby/object:Gem::Version
1516
- hash: 23
1517
1504
  segments:
1518
1505
  - 1
1519
1506
  - 3