radiant-images-extension 0.1.1 → 0.3.2
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/CHANGELOG +9 -0
- data/README.md +11 -0
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/app/controllers/admin/images_controller.rb +2 -8
- data/app/models/image.rb +10 -7
- data/app/views/admin/images/_bottom.haml +2 -2
- data/app/views/admin/images/remove.haml +2 -2
- data/config/locales/en.yml +5 -5
- data/db/migrate/20100929150930_change_images_to_created_by_id.rb +15 -0
- data/images_extension.rb +3 -1
- data/lib/images/tags/core.rb +295 -0
- data/lib/images/tags/helpers.rb +64 -0
- data/lib/tasks/images_extension_tasks.rake +1 -0
- data/public/images/admin/extensions/images/sort.png +0 -0
- data/radiant-images-extension.gemspec +9 -5
- data/spec/controllers/admin/images_controller_spec.rb +17 -81
- data/spec/datasets/images.rb +1 -1
- data/spec/lib/images/tags/core_spec.rb +110 -0
- data/spec/models/image_spec.rb +2 -2
- metadata +12 -8
- data/lib/images/tags/image.rb +0 -171
- data/spec/lib/images/tags/image_spec.rb +0 -240
data/CHANGELOG
ADDED
data/README.md
CHANGED
@@ -26,6 +26,17 @@ Radiant Images is an IMAGE management tool, meant only to be useful to pages and
|
|
26
26
|
|
27
27
|
rake radiant:extensions:images:migrate_from_paperclipped
|
28
28
|
|
29
|
+
## Installation
|
30
|
+
|
31
|
+
The recommended way to install the radiant images extension is by installing the gem and configuring it in your radiant app, here are the instructions:
|
32
|
+
|
33
|
+
gem install radiant-images-extension
|
34
|
+
# add the following line to your config/environment.rb: config.gem 'radiant-images-extension', :lib => false
|
35
|
+
rake radiant:extensions:images:update
|
36
|
+
rake radiant:extensions:images:migrate
|
37
|
+
|
38
|
+
If you want to run a development copy of images simply clone a copy into radiant's vendor/extensions folder and then run a update/migrate on the extension.
|
39
|
+
|
29
40
|
## Host Alias Settings
|
30
41
|
|
31
42
|
By default the images extension uses the following url for images:
|
data/Rakefile
CHANGED
@@ -14,6 +14,7 @@ begin
|
|
14
14
|
gem.add_development_dependency 'rr', '>= 1.0.0'
|
15
15
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
16
|
end
|
17
|
+
Jeweler::GemcutterTasks.new
|
17
18
|
rescue LoadError
|
18
19
|
puts "Jeweler (or a dependency) not available. This is only required if you plan to package images as a gem."
|
19
20
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.2
|
@@ -2,13 +2,7 @@ class Admin::ImagesController < Admin::ResourceController
|
|
2
2
|
|
3
3
|
before_filter :index_assets, :only => [ :index ]
|
4
4
|
before_filter :edit_assets, :only => [ :show, :edit ]
|
5
|
-
around_filter :
|
6
|
-
|
7
|
-
# GET /admin/images
|
8
|
-
# GET /admin/images.js
|
9
|
-
# GET /admin/images.xml
|
10
|
-
# GET /admin/images.json AJAX and HTML
|
11
|
-
#----------------------------------------------------------------------------
|
5
|
+
around_filter :rescue_s3_exceptions, :only => [:create, :edit, :destroy]
|
12
6
|
|
13
7
|
def index
|
14
8
|
@images = Image.paginate :page => params[:page], :per_page => 20
|
@@ -38,7 +32,7 @@ private
|
|
38
32
|
include_stylesheet 'admin/extensions/images/edit'
|
39
33
|
end
|
40
34
|
|
41
|
-
def
|
35
|
+
def rescue_s3_exceptions
|
42
36
|
begin
|
43
37
|
yield
|
44
38
|
rescue AWS::S3::ResponseError => e
|
data/app/models/image.rb
CHANGED
@@ -9,7 +9,7 @@ class Image < ActiveRecord::Base
|
|
9
9
|
|
10
10
|
default_scope :order => 'position ASC'
|
11
11
|
acts_as_list
|
12
|
-
|
12
|
+
|
13
13
|
has_attached_file :asset,
|
14
14
|
:styles => lambda { Image.config_styles },
|
15
15
|
:whiny_thumbnails => false,
|
@@ -25,13 +25,16 @@ class Image < ActiveRecord::Base
|
|
25
25
|
|
26
26
|
validates_attachment_presence :asset
|
27
27
|
validates_attachment_content_type :asset, :content_type => ['image/jpeg', 'image/png', 'image/gif']
|
28
|
-
|
28
|
+
|
29
29
|
def assign_title
|
30
30
|
self.title = self.asset_file_name if title.blank?
|
31
31
|
end
|
32
|
-
|
33
32
|
|
34
|
-
|
33
|
+
def url(style = :original, include_updated_timestamp = true, secure = false)
|
34
|
+
self.asset.url(style, include_updated_timestamp, secure)
|
35
|
+
end
|
36
|
+
|
37
|
+
# We need to overide the url method for our attachment so
|
35
38
|
# we can dynamically swap between aliased and non aliased domain names
|
36
39
|
module ::Paperclip
|
37
40
|
class Attachment
|
@@ -58,7 +61,7 @@ class Image < ActiveRecord::Base
|
|
58
61
|
end
|
59
62
|
|
60
63
|
private
|
61
|
-
|
64
|
+
|
62
65
|
class << self
|
63
66
|
def search(search, page)
|
64
67
|
unless search.blank?
|
@@ -66,7 +69,7 @@ private
|
|
66
69
|
queries << 'LOWER(title) LIKE (:term)'
|
67
70
|
queries << 'LOWER(caption) LIKE (:term)'
|
68
71
|
queries << 'LOWER(asset_file_name) LIKE (:term)'
|
69
|
-
|
72
|
+
|
70
73
|
sql = queries.join(' OR ')
|
71
74
|
@conditions = [sql, {:term => "%#{search.downcase}%" }]
|
72
75
|
else
|
@@ -79,7 +82,7 @@ private
|
|
79
82
|
|
80
83
|
def config_styles
|
81
84
|
styles = []
|
82
|
-
|
85
|
+
|
83
86
|
if Radiant::Config['images.styles']
|
84
87
|
styles = Radiant::Config['images.styles'].gsub(/\s+/,'').split(',')
|
85
88
|
styles = styles.collect{|s| s.split('=')}.inject({}) {|ha, (k, v)| ha[k.to_sym] = v; ha}
|
@@ -7,7 +7,7 @@
|
|
7
7
|
%li
|
8
8
|
- form_tag nil, :method => 'get' do
|
9
9
|
= text_field_tag 'search', params[:search], :type => 'search'
|
10
|
-
= observe_field 'search', :frequency => 2, :update => 'images', :url => { :controller => 'images', :action=> '
|
10
|
+
= observe_field 'search', :frequency => 2, :update => 'images', :url => { :controller => 'images', :action=> 'index' }, :method => 'get', :with => "'search=' + escape(value)"
|
11
11
|
- render_region :paginate do |paginate|
|
12
12
|
- paginate.pagination do
|
13
|
-
=
|
13
|
+
= pagination_for(@images)
|
@@ -2,9 +2,9 @@
|
|
2
2
|
= t('remove_image')
|
3
3
|
|
4
4
|
%p
|
5
|
-
= t('
|
5
|
+
= t('remove_image_warning')
|
6
6
|
|
7
|
-
- form_for [:admin, @image.becomes(Image)], :html => {:method => :delete, 'data-onsubmit_status'=>"
|
7
|
+
- form_for [:admin, @image.becomes(Image)], :html => {:method => :delete, 'data-onsubmit_status'=>"#{t('deleting_image')}…"} do
|
8
8
|
|
9
9
|
%p.buttons
|
10
10
|
%input.button{:type=>"submit", :value => t('delete_image') }/
|
data/config/locales/en.yml
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
---
|
2
2
|
en:
|
3
3
|
images: Images
|
4
|
-
new_image:
|
5
|
-
remove_image:
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
new_image: New Image
|
5
|
+
remove_image: Remove Image
|
6
|
+
remove_image_warning: Are you sure you want to delete this image as well as its ties to any other parts of the site?
|
7
|
+
delete_image: Delete Image
|
8
|
+
deleting_image: Deleting Image
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class ChangeImagesToCreatedById < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :images, :created_by_id, :integer
|
4
|
+
add_column :images, :updated_by_id, :integer
|
5
|
+
remove_column :images, :created_by
|
6
|
+
remove_column :images, :updated_by
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.down
|
10
|
+
add_column :images, :created_by_id, :integer
|
11
|
+
add_column :images, :updated_by_id, :integer
|
12
|
+
remove_column :images, :created_by
|
13
|
+
remove_column :images, :updated_by
|
14
|
+
end
|
15
|
+
end
|
data/images_extension.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# Uncomment this if you reference any of your controllers in activate
|
2
2
|
# require_dependency 'application_controller'
|
3
3
|
|
4
|
+
require 'paperclip'
|
5
|
+
|
4
6
|
class ImagesExtension < Radiant::Extension
|
5
7
|
version "0.1"
|
6
8
|
description "Images stores images on s3"
|
@@ -32,7 +34,7 @@ class ImagesExtension < Radiant::Extension
|
|
32
34
|
end
|
33
35
|
|
34
36
|
|
35
|
-
Page.send :include, Images::Tags::
|
37
|
+
Page.send :include, Images::Tags::Core
|
36
38
|
|
37
39
|
UserActionObserver.instance.send :add_observer!, Image
|
38
40
|
|
@@ -0,0 +1,295 @@
|
|
1
|
+
module Images
|
2
|
+
module Tags
|
3
|
+
module Core
|
4
|
+
include Radiant::Taggable
|
5
|
+
|
6
|
+
class TagError < StandardError; end
|
7
|
+
|
8
|
+
desc %{
|
9
|
+
The namespace for referencing images. You may specify the title
|
10
|
+
attribute for this tag to use only images with the specified title.
|
11
|
+
|
12
|
+
*Usage:*
|
13
|
+
<pre><code><r:images>...</r:images></code></pre>
|
14
|
+
}
|
15
|
+
tag 'images' do |tag|
|
16
|
+
tag.locals.images = Helpers.current_images(tag)
|
17
|
+
|
18
|
+
tag.expand
|
19
|
+
end
|
20
|
+
|
21
|
+
desc %{
|
22
|
+
Expands if images exist
|
23
|
+
}
|
24
|
+
tag 'images:if_images' do |tag|
|
25
|
+
tag.expand if tag.locals.images.present?
|
26
|
+
end
|
27
|
+
|
28
|
+
desc %{
|
29
|
+
Expands unless images exist
|
30
|
+
}
|
31
|
+
tag 'images:unless_images' do |tag|
|
32
|
+
tag.expand unless tag.locals.images.present?
|
33
|
+
end
|
34
|
+
|
35
|
+
desc %{
|
36
|
+
Goes through each of the available images.
|
37
|
+
Use the limit and offset attributes to render a specific number of images.
|
38
|
+
Use the by and order attributes to control the order of images.
|
39
|
+
|
40
|
+
*Usage:*
|
41
|
+
<pre><code><r:images:each [limit=0] [offset=0] [order="asc|desc"] [by="position|title|..."]>...</r:images:each></code></pre>
|
42
|
+
}
|
43
|
+
tag 'images:each' do |tag|
|
44
|
+
context = ''
|
45
|
+
|
46
|
+
tag.locals.images.each do |image|
|
47
|
+
tag.locals.image = image
|
48
|
+
context << tag.expand
|
49
|
+
end
|
50
|
+
|
51
|
+
content
|
52
|
+
end
|
53
|
+
|
54
|
+
desc %{
|
55
|
+
Expands the current image context
|
56
|
+
|
57
|
+
*Usage:*
|
58
|
+
<pre><code><r:image>...</r:image></code></pre>
|
59
|
+
}
|
60
|
+
tag 'image' do |tag|
|
61
|
+
tag.locals.image = Helpers.current_image(tag)
|
62
|
+
|
63
|
+
tag.expand if tag.locals.image.present?
|
64
|
+
end
|
65
|
+
|
66
|
+
desc %{
|
67
|
+
Outputs the full URL of the image including the filename. Specify the style
|
68
|
+
using the style option.
|
69
|
+
|
70
|
+
*Usage:*
|
71
|
+
<pre><code><r:image title='image'><r:url [style="preview|original"] /></r:image></code></pre>
|
72
|
+
}
|
73
|
+
tag 'image:url' do |tag|
|
74
|
+
style = tag.attr['style'] || :original
|
75
|
+
|
76
|
+
tag.locals.image.url(style, false)
|
77
|
+
end
|
78
|
+
|
79
|
+
[:id, :title].each do |method|
|
80
|
+
desc %{
|
81
|
+
Outputs the title of the current image
|
82
|
+
|
83
|
+
*Usage:*
|
84
|
+
<pre><code><r:image title='image'><r:#{method} /></code></pre>
|
85
|
+
}
|
86
|
+
tag "image:#{method}" do |tag|
|
87
|
+
tag.locals.image.send(method)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
# describe '<r:images:each>' do
|
98
|
+
#
|
99
|
+
# it 'should expand on all images' do
|
100
|
+
# content = '<r:images:each>test!</r:images:each>'
|
101
|
+
# expected = ''
|
102
|
+
# @images.length.times { expected += 'test!' }
|
103
|
+
# pages(:home).should render(content).as(expected)
|
104
|
+
# end
|
105
|
+
#
|
106
|
+
# it 'should be running through the image objects' do
|
107
|
+
# content = '<r:images:each><r:images:url/></r:images:each>'
|
108
|
+
# expected = ''
|
109
|
+
# @images.each { |image| expected += image.asset.url }
|
110
|
+
# pages(:home).should render(content).as(expected)
|
111
|
+
# end
|
112
|
+
#
|
113
|
+
# it 'should only run through however many images we specify with limit' do
|
114
|
+
# content = '<r:images:each limit="2"><r:images:url/></r:images:each>'
|
115
|
+
# expected = ''
|
116
|
+
# @images[0..1].each { |image| expected += image.asset.url }
|
117
|
+
# pages(:home).should render(content).as(expected)
|
118
|
+
# end
|
119
|
+
#
|
120
|
+
# it 'should start at the image number we give it using offset' do
|
121
|
+
# content = '<r:images:each limit="2" offset="1"><r:images:url/></r:images:each>'
|
122
|
+
# expected = ''
|
123
|
+
# @images[1..2].each { |image| expected += image.asset.url }
|
124
|
+
# pages(:home).should render(content).as(expected)
|
125
|
+
# end
|
126
|
+
#
|
127
|
+
# it 'should display images in the order we give' do
|
128
|
+
# # asc
|
129
|
+
# content = '<r:images:each order="asc" by="position"><r:images:url/></r:images:each>'
|
130
|
+
# expected = ''
|
131
|
+
# @images.each { |image| expected += image.asset.url }
|
132
|
+
# pages(:home).should render(content).as(expected)
|
133
|
+
#
|
134
|
+
# #desc
|
135
|
+
# content = '<r:images:each order="desc" by="position"><r:images:url/></r:images:each>'
|
136
|
+
# expected = ''
|
137
|
+
# @images.reverse.each { |image| expected += image.asset.url }
|
138
|
+
# pages(:home).should render(content).as(expected)
|
139
|
+
# end
|
140
|
+
#
|
141
|
+
# it 'should allow us to order images by title' do
|
142
|
+
# content = '<r:images:each order="asc" by="title"><r:images:url/></r:images:each>'
|
143
|
+
# expected = ''
|
144
|
+
# @images.sort! { |a,b| a.title <=> b.title }
|
145
|
+
# @images.each { |image| expected += image.asset.url }
|
146
|
+
# pages(:home).should render(content).as(expected)
|
147
|
+
# end
|
148
|
+
#
|
149
|
+
# end
|
150
|
+
#
|
151
|
+
# describe '<r:images:first>' do
|
152
|
+
#
|
153
|
+
# it 'should render the first image' do
|
154
|
+
# content = '<r:images:first><r:images:url/></r:images:first>'
|
155
|
+
# expected = @images.first.asset.url
|
156
|
+
# pages(:home).should render(content).as(expected)
|
157
|
+
# end
|
158
|
+
#
|
159
|
+
# end
|
160
|
+
#
|
161
|
+
# describe '<r:images:if_first>' do
|
162
|
+
#
|
163
|
+
# it 'should expand the tag if the image is the first' do
|
164
|
+
# content = '<r:images><r:each><r:if_first><r:url /></r:if_first></r:each></r:images>'
|
165
|
+
# expected = @images.first.asset.url
|
166
|
+
# pages(:home).should render(content).as(expected)
|
167
|
+
# end
|
168
|
+
#
|
169
|
+
# end
|
170
|
+
#
|
171
|
+
# describe '<r:images:unless_first>' do
|
172
|
+
#
|
173
|
+
# it 'should expand the tag if the image is not the first' do
|
174
|
+
# content = '<r:images><r:each><r:unless_first><r:url /></r:unless_first></r:each></r:images>'
|
175
|
+
# expected = ''
|
176
|
+
#
|
177
|
+
# @images.each do |image|
|
178
|
+
# expected += image.asset.url unless image == @images.first
|
179
|
+
# end
|
180
|
+
#
|
181
|
+
# pages(:home).should render(content).as(expected)
|
182
|
+
# end
|
183
|
+
#
|
184
|
+
# end
|
185
|
+
#
|
186
|
+
# describe '<r:if_images>' do
|
187
|
+
#
|
188
|
+
# it 'should expand the contents if there are images' do
|
189
|
+
# content = '<r:images:if_images>test text</r:images:if_images>'
|
190
|
+
# expected = 'test text'
|
191
|
+
# pages(:home).should render(content).as(expected)
|
192
|
+
# end
|
193
|
+
#
|
194
|
+
# it 'should not expand the contents if there are no images' do
|
195
|
+
# Image.delete_all
|
196
|
+
# content = '<r:images:if_images>test text</r:images:if_images>'
|
197
|
+
# expected = ''
|
198
|
+
# pages(:home).should render(content).as(expected)
|
199
|
+
# end
|
200
|
+
#
|
201
|
+
# it 'should expand if the min count is equal to the image count' do
|
202
|
+
# min_count = Image.count
|
203
|
+
# content = '<r:images:if_images min_count="' + min_count.to_s + '">test text</r:images:if_images>'
|
204
|
+
# expected = 'test text'
|
205
|
+
# pages(:home).should render(content).as(expected)
|
206
|
+
# end
|
207
|
+
#
|
208
|
+
# it 'should not expand if the min count is greater than the image count' do
|
209
|
+
# min_count = Image.count + 1
|
210
|
+
# content = '<r:images:if_images min_count="' + min_count.to_s + '">test text</r:images:if_images>'
|
211
|
+
# expected = ''
|
212
|
+
# pages(:home).should render(content).as(expected)
|
213
|
+
# end
|
214
|
+
#
|
215
|
+
# end
|
216
|
+
#
|
217
|
+
# describe '<r:unless_images>' do
|
218
|
+
#
|
219
|
+
# it 'should not the contents if there are images' do
|
220
|
+
# content = '<r:images:unless_images>test text</r:images:unless_images>'
|
221
|
+
# expected = ''
|
222
|
+
# pages(:home).should render(content).as(expected)
|
223
|
+
# end
|
224
|
+
#
|
225
|
+
# it 'should expand the contents if there are no images' do
|
226
|
+
# Image.delete_all
|
227
|
+
# content = '<r:images:unless_images>test text</r:images:unless_images>'
|
228
|
+
# expected = 'test text'
|
229
|
+
# pages(:home).should render(content).as(expected)
|
230
|
+
# end
|
231
|
+
#
|
232
|
+
# it 'should not expand if the min count is equal to the image count' do
|
233
|
+
# min_count = Image.count
|
234
|
+
# content = '<r:images:unless_images min_count="' + min_count.to_s + '">test text</r:images:unless_images>'
|
235
|
+
# expected = ''
|
236
|
+
# pages(:home).should render(content).as(expected)
|
237
|
+
# end
|
238
|
+
#
|
239
|
+
# it 'should expand if the min count is greater than the image count' do
|
240
|
+
# min_count = Image.count + 1
|
241
|
+
# content = '<r:images:unless_images min_count="' + min_count.to_s + '">test text</r:images:unless_images>'
|
242
|
+
# expected = 'test text'
|
243
|
+
# pages(:home).should render(content).as(expected)
|
244
|
+
# end
|
245
|
+
#
|
246
|
+
# end
|
247
|
+
#
|
248
|
+
# describe '<r:images:url/>' do
|
249
|
+
#
|
250
|
+
# it 'should output the url for a valid image' do
|
251
|
+
# content = '<r:images title="' + @images.first.title + '"><r:images:url/></r:images>'
|
252
|
+
# expected = @images.first.asset.url
|
253
|
+
# pages(:home).should render(content).as(expected)
|
254
|
+
# end
|
255
|
+
#
|
256
|
+
# end
|
257
|
+
#
|
258
|
+
# describe '<r:images:title/>' do
|
259
|
+
#
|
260
|
+
# it 'should output the title for a valid image' do
|
261
|
+
# content = '<r:images title="' + @images.first.title + '"><r:images:title/></r:images>'
|
262
|
+
# expected = @images.first.title
|
263
|
+
# pages(:home).should render(content).as(expected)
|
264
|
+
# end
|
265
|
+
#
|
266
|
+
# end
|
267
|
+
#
|
268
|
+
# describe '<r:images:tag/>' do
|
269
|
+
#
|
270
|
+
# it 'should output a valid image tag when given a valid image' do
|
271
|
+
# content = '<r:images title="' + @images.first.title + '"><r:images:tag /></r:images>'
|
272
|
+
# expected = '<img src="' + @images.first.asset.url + '" alt="' + @images.first.title + '" />'
|
273
|
+
# pages(:home).should render(content).as(expected)
|
274
|
+
# end
|
275
|
+
#
|
276
|
+
# it 'should output a valid image tag when specifying an image by title' do
|
277
|
+
# content = '<r:images:tag title="' + @images.first.title + '" />'
|
278
|
+
# expected = '<img src="' + @images.first.asset.url + '" alt="' + @images.first.title + '" />'
|
279
|
+
# pages(:home).should render(content).as(expected)
|
280
|
+
# end
|
281
|
+
#
|
282
|
+
# it 'should output an image tag with the specified size' do
|
283
|
+
# content = '<r:images:tag title="' + @images.first.title + '" size="icon" />'
|
284
|
+
# expected = '<img src="' + @images.first.asset.url(:icon) + '" alt="' + @images.first.title + '" />'
|
285
|
+
# pages(:home).should render(content).as(expected)
|
286
|
+
# end
|
287
|
+
#
|
288
|
+
# it 'should use the given alt text specified' do
|
289
|
+
# content = '<r:images:tag title="' + @images.first.title + '" alt="new alt text" />'
|
290
|
+
# expected = '<img src="' + @images.first.asset.url + '" alt="new alt text" />'
|
291
|
+
# pages(:home).should render(content).as(expected)
|
292
|
+
# end
|
293
|
+
#
|
294
|
+
# end
|
295
|
+
#
|