radiant-page_attachments-extension 1.0.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.
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.md +129 -0
- data/Rakefile +57 -0
- data/VERSION +1 -0
- data/app/models/observe_page_attachments.rb +5 -0
- data/app/models/page_attachment.rb +28 -0
- data/app/models/page_attachment_associations.rb +20 -0
- data/app/models/page_attachment_tags.rb +261 -0
- data/app/models/page_attachments_interface.rb +19 -0
- data/app/views/admin/pages/_attachment.html.haml +12 -0
- data/app/views/admin/pages/_attachments_box.html.haml +12 -0
- data/db/migrate/001_create_page_attachments_extension_schema.rb +22 -0
- data/db/migrate/002_add_page_attachments_fields.rb +23 -0
- data/features/attachments.feature +42 -0
- data/features/step_definitions/attachment_steps.rb +61 -0
- data/features/support/env.rb +57 -0
- data/features/support/paths.rb +14 -0
- data/lib/difference_test_helper.rb +20 -0
- data/lib/radiant-page_attachments-extension.rb +0 -0
- data/lib/tasks/page_attachments_extension_tasks.rake +28 -0
- data/page_attachments_extension.rb +27 -0
- data/public/images/admin/drag_order.png +0 -0
- data/public/javascripts/admin/page_attachments.js +30 -0
- data/public/stylesheets/admin/page_attachments.css +133 -0
- data/radiant-page_attachments-extension.gemspec +139 -0
- data/spec/controllers/pages_controller_spec.rb +10 -0
- data/spec/datasets/page_attachments_dataset.rb +31 -0
- data/spec/fixtures/foo.txt +1 -0
- data/spec/fixtures/rails.png +0 -0
- data/spec/models/observe_page_attachments_spec.rb +14 -0
- data/spec/models/page_attachment_spec.rb +18 -0
- data/spec/models/page_attachment_tags_spec.rb +172 -0
- data/spec/models/page_spec.rb +32 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +39 -0
- data/vendor/plugins/acts_as_list/README +23 -0
- data/vendor/plugins/acts_as_list/init.rb +3 -0
- data/vendor/plugins/acts_as_list/lib/active_record/acts/list.rb +256 -0
- data/vendor/plugins/acts_as_list/test/list_test.rb +332 -0
- data/vendor/plugins/attachment_fu/CHANGELOG +35 -0
- data/vendor/plugins/attachment_fu/LICENSE +20 -0
- data/vendor/plugins/attachment_fu/README +193 -0
- data/vendor/plugins/attachment_fu/Rakefile +22 -0
- data/vendor/plugins/attachment_fu/amazon_s3.yml.tpl +17 -0
- data/vendor/plugins/attachment_fu/init.rb +16 -0
- data/vendor/plugins/attachment_fu/install.rb +7 -0
- data/vendor/plugins/attachment_fu/lib/geometry.rb +93 -0
- data/vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/backends/cloud_file_backend.rb +211 -0
- data/vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/backends/db_file_backend.rb +39 -0
- data/vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/backends/file_system_backend.rb +126 -0
- data/vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/backends/s3_backend.rb +394 -0
- data/vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/processors/core_image_processor.rb +59 -0
- data/vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/processors/gd2_processor.rb +54 -0
- data/vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/processors/image_science_processor.rb +61 -0
- data/vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/processors/mini_magick_processor.rb +132 -0
- data/vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/processors/rmagick_processor.rb +57 -0
- data/vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu.rb +514 -0
- data/vendor/plugins/attachment_fu/rackspace_cloudfiles.yml.tpl +14 -0
- data/vendor/plugins/attachment_fu/test/backends/db_file_test.rb +16 -0
- data/vendor/plugins/attachment_fu/test/backends/file_system_test.rb +143 -0
- data/vendor/plugins/attachment_fu/test/backends/remote/cloudfiles_test.rb +102 -0
- data/vendor/plugins/attachment_fu/test/backends/remote/s3_test.rb +119 -0
- data/vendor/plugins/attachment_fu/test/base_attachment_tests.rb +77 -0
- data/vendor/plugins/attachment_fu/test/basic_test.rb +70 -0
- data/vendor/plugins/attachment_fu/test/database.yml +18 -0
- data/vendor/plugins/attachment_fu/test/extra_attachment_test.rb +67 -0
- data/vendor/plugins/attachment_fu/test/fixtures/attachment.rb +226 -0
- data/vendor/plugins/attachment_fu/test/fixtures/files/fake/rails.png +0 -0
- data/vendor/plugins/attachment_fu/test/fixtures/files/foo.txt +1 -0
- data/vendor/plugins/attachment_fu/test/fixtures/files/rails.png +0 -0
- data/vendor/plugins/attachment_fu/test/geometry_test.rb +108 -0
- data/vendor/plugins/attachment_fu/test/processors/core_image_test.rb +37 -0
- data/vendor/plugins/attachment_fu/test/processors/gd2_test.rb +31 -0
- data/vendor/plugins/attachment_fu/test/processors/image_science_test.rb +31 -0
- data/vendor/plugins/attachment_fu/test/processors/mini_magick_test.rb +103 -0
- data/vendor/plugins/attachment_fu/test/processors/rmagick_test.rb +255 -0
- data/vendor/plugins/attachment_fu/test/schema.rb +134 -0
- data/vendor/plugins/attachment_fu/test/test_helper.rb +150 -0
- data/vendor/plugins/attachment_fu/test/validation_test.rb +55 -0
- data/vendor/plugins/attachment_fu/vendor/red_artisan/core_image/filters/color.rb +27 -0
- data/vendor/plugins/attachment_fu/vendor/red_artisan/core_image/filters/effects.rb +31 -0
- data/vendor/plugins/attachment_fu/vendor/red_artisan/core_image/filters/perspective.rb +25 -0
- data/vendor/plugins/attachment_fu/vendor/red_artisan/core_image/filters/quality.rb +25 -0
- data/vendor/plugins/attachment_fu/vendor/red_artisan/core_image/filters/scale.rb +47 -0
- data/vendor/plugins/attachment_fu/vendor/red_artisan/core_image/filters/watermark.rb +32 -0
- data/vendor/plugins/attachment_fu/vendor/red_artisan/core_image/processor.rb +123 -0
- metadata +178 -0
data/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2010 Sean Cribbs
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
Page Attachments
|
|
2
|
+
===
|
|
3
|
+
|
|
4
|
+
About
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
A [Radiant][rd] Extension by [Sean Cribbs][sc] that adds page-attachment-style asset management. Page Attachments adds support for file uploads realized as attachments to individual pages. Attachments can have an order via acts_as_list, a title, a description and various metadata fields as provided by AttachmentFu.
|
|
8
|
+
|
|
9
|
+
Installation
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
If you want `page_attachments` to generate and display thumbnails of your uploaded images you'll first need to install one of, [`image_science`][is], [`mini-magick`][mm] or [`rmagick`][rm] on your server. This is completely optional, `page_attachments` will still function in every other way without any of these packages installed.
|
|
13
|
+
|
|
14
|
+
Now you're ready to install `page_attachments`.
|
|
15
|
+
|
|
16
|
+
cd /path/to/radiant
|
|
17
|
+
git clone git://github.com/radiant/radiant-page-attachments-extension.git vendor/extensions/page_attachments
|
|
18
|
+
rake radiant:extensions:page_attachments:migrate
|
|
19
|
+
rake radiant:extensions:page_attachments:update
|
|
20
|
+
|
|
21
|
+
If you don't have `git` you can [download a tarball][pa].
|
|
22
|
+
|
|
23
|
+
Attachment thumbnails for images default to `:icon => '50x50>'`. You can customize that by setting
|
|
24
|
+
`PAGE_ATTACHMENT_SIZES` to whatever you need in your `config/environment.rb` file
|
|
25
|
+
|
|
26
|
+
PAGE_ATTACHMENT_SIZES = {:thumb => '120x120>', :normal => '640x480>'}
|
|
27
|
+
|
|
28
|
+
Restart your server and refresh the admin interface.
|
|
29
|
+
|
|
30
|
+
Running features and specs
|
|
31
|
+
---
|
|
32
|
+
The Cucumber features use Webrat and Selenium. You'll need the webrat 0.5.1 and selenium-client 1.2.16 gems installed and you'll need to change the version of webrat specified in environments/test.rb.
|
|
33
|
+
|
|
34
|
+
Managing Attachments
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
Now when you login and edit a page, you'll find the "Attachments" interface below the text editing area. To add a new attachment to the page click the **+** icon. If you need to you can upload multiple attachments at once by clicking the **+** icon once for each attachment you'll be adding. Attachments are **not** added or deleted until the page is saved. Therefore, if you accidentally deleted something you meant to keep, simply cancel the page edit.
|
|
38
|
+
|
|
39
|
+
Usage
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
* See the "available tags" documentation built into the Radiant page admin for more details.
|
|
43
|
+
* Reference an attachment by name `<r:attachment name="file.txt">...</r:attachment>`
|
|
44
|
+
* Display an attachment's URL `<r:attachment:url name="file.jpg"/>`
|
|
45
|
+
* Display an attachment's `#{key}` attribute `<r:attachment:#{key} name="file.jpg"/>`
|
|
46
|
+
* Display the date an attachment was added `<r:attachment:date name="file.txt"/>`
|
|
47
|
+
* Display an attached image `<r:attachment:image name="file.jpg"/>`
|
|
48
|
+
* Display a link to an attachment `<r:attachment:link name="file.jpg"/>` or `<r:attachment:link name="file.jpg">Click Here</r:attachment:link>`
|
|
49
|
+
* Display name of the user who added the attachment `<r:attachment:author name="file.jpg"/>`
|
|
50
|
+
* Iterate through all the attachments on a page `<r:attachment:each><r:link/></r:attachment:each>`
|
|
51
|
+
* Display the extension of an attachement inside iterations with <r:attachment:extension/>
|
|
52
|
+
|
|
53
|
+
Troubleshooting
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
If you have a problem running the migrate task, and it fails with an error something like this:
|
|
57
|
+
|
|
58
|
+
ld: library not found for -lfreeimage
|
|
59
|
+
collect2: ld returned 1 exit status
|
|
60
|
+
|
|
61
|
+
It means you have installed the ImageScience gem but you don't have FreeImage installed. So, either install FreeImage or uninstall the gem with
|
|
62
|
+
|
|
63
|
+
gem uninstall image_science
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
If you're using ImageScience as a user without a home directory, you may see this error:
|
|
68
|
+
|
|
69
|
+
Define INLINEDIR or HOME in your environment and try again
|
|
70
|
+
|
|
71
|
+
This is caused by RubyInline not having a place to store its generated files and can be easily fixed by specifying a path in your environment file like so:
|
|
72
|
+
|
|
73
|
+
ENV['INLINEDIR'] = File.join(RAILS_ROOT,'tmp','ruby_inline')
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
If you have trouble attaching files to Page Types other than the normal type, try editing the following line in your `config/environment.rb` file
|
|
78
|
+
|
|
79
|
+
config.extensions = [ :all ]
|
|
80
|
+
|
|
81
|
+
to look like
|
|
82
|
+
|
|
83
|
+
config.extensions = [ :page_attachments, :all ]
|
|
84
|
+
|
|
85
|
+
Amazon S3 for Attachment storage
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
Since `page_attachments` uses `attachment_fu` for the handling of attachments it's just as easy to use [S3][s3] as it is to use your hard drive. Before you get started with this there are a few things to keep in mind:
|
|
89
|
+
|
|
90
|
+
* If you've already started storing attachments on your hard drive **this will break** any `<r:attachment...>` tags pointing to those files. You'll need to remove all existing attachments and re-add them to Amazon S3.
|
|
91
|
+
* You have to install the `AWS::S3` gem. In some shared hosting environments this might not be possible.
|
|
92
|
+
* The `AWS::S3` gem does not (currently) support EU buckets, so if that's all you have you'll need to create a bucket in the US.
|
|
93
|
+
|
|
94
|
+
Before you start make sure you have `page_attachments` working using your hard drive. Once you've tested an upload or two to the hard drive and feel confident the basic setup is working, dive right in.
|
|
95
|
+
|
|
96
|
+
1. `gem install aws-s3`
|
|
97
|
+
2. `cd /path/to/radiant`
|
|
98
|
+
3. `cp vendor/plugins/attachment_fu/amazon_s3.yml.tpl config/amazon_s3.yml`
|
|
99
|
+
4. edit `config/amazon_s3.yml` with your S3 credentials
|
|
100
|
+
5. `cp vendor/extensions/page_attachments/app/models/page_attachment.rb vendor/extensions/page_attachments/app/models/page_attachment.rb.bak`
|
|
101
|
+
6. edit line 2 of `vendor/extensions/page_attachments/app/models/page_attachment.rb` changing `:file_system` to `:s3`
|
|
102
|
+
7. restart your server
|
|
103
|
+
|
|
104
|
+
Add an attachment and make sure the link it gives back is on S3. You should see all your attachments start showing up at `http://s3.amazonaws.com/bucket-name/page_attachments/`. While it is possible to customize the URL to Amazon (i.e. http://attachments.your-domain.com/) but it's beyond the scope of this document and a task best left for those that really need custom URLs.
|
|
105
|
+
|
|
106
|
+
Contributors
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
These people have contributed patches that have been added to the extension:
|
|
110
|
+
|
|
111
|
+
* [John Muhl][jm]
|
|
112
|
+
* [Daniel Collis-Puro][djcp]
|
|
113
|
+
* [James Burka][jb]
|
|
114
|
+
* [Istvan Hoka][ihoka]
|
|
115
|
+
* [Oleg Ivanov][oleg]
|
|
116
|
+
|
|
117
|
+
[rd]: http://radiantcms.org/
|
|
118
|
+
[sc]: http://seancribbs.com/
|
|
119
|
+
[is]: http://seattlerb.rubyforge.org/ImageScience.html
|
|
120
|
+
[mm]: http://rubyforge.org/projects/mini-magick/
|
|
121
|
+
[rm]: http://rmagick.rubyforge.org/
|
|
122
|
+
[af]: http://github.com/technoweenie/attachment_fu/tarball/master
|
|
123
|
+
[pa]: http://github.com/radiant/radiant-page-attachments-extension/tarball/master
|
|
124
|
+
[s3]: http://www.amazon.com/gp/browse.html?node=16427261
|
|
125
|
+
[jm]: http://github.com/johnmuhl
|
|
126
|
+
[djcp]: http://www.kookdujour.com/
|
|
127
|
+
[jb]: http://github.com/jjburka
|
|
128
|
+
[ihoka]: http://github.com/ihoka
|
|
129
|
+
[oleg]: http://github.com/morhekil
|
data/Rakefile
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'rake'
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
require 'jeweler'
|
|
6
|
+
Jeweler::Tasks.new do |gem|
|
|
7
|
+
gem.name = "radiant-page_attachments-extension"
|
|
8
|
+
gem.summary = %Q{Adds page-attachment-style asset management.}
|
|
9
|
+
gem.description = %Q{Page Attachments adds support for file uploads realized as attachments to individual pages. Attachments can have an order via acts_as_list, a title, a description and various metadata fields as provided by AttachmentFu.}
|
|
10
|
+
gem.email = "radiant@radiantcms.org"
|
|
11
|
+
gem.homepage = "http://github.com/radiant/radiant-page-attachments-extension"
|
|
12
|
+
gem.authors = ["Sean Cribbs"]
|
|
13
|
+
gem.add_development_dependency "rspec"
|
|
14
|
+
gem.add_development_dependency "cucumber"
|
|
15
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
|
16
|
+
end
|
|
17
|
+
Jeweler::GemcutterTasks.new
|
|
18
|
+
rescue LoadError
|
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
require 'spec/rake/spectask'
|
|
23
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
|
24
|
+
spec.libs << 'lib' << 'spec'
|
|
25
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
|
29
|
+
spec.libs << 'lib' << 'spec'
|
|
30
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
|
31
|
+
spec.rcov = true
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
task :spec => :check_dependencies
|
|
35
|
+
|
|
36
|
+
begin
|
|
37
|
+
require 'cucumber/rake/task'
|
|
38
|
+
Cucumber::Rake::Task.new(:features)
|
|
39
|
+
|
|
40
|
+
task :features => :check_dependencies
|
|
41
|
+
rescue LoadError
|
|
42
|
+
task :features do
|
|
43
|
+
abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
task :default => :spec
|
|
48
|
+
|
|
49
|
+
require 'rake/rdoctask'
|
|
50
|
+
Rake::RDocTask.new do |rdoc|
|
|
51
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
|
52
|
+
|
|
53
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
54
|
+
rdoc.title = "radiant-page_attachments-extension #{version}"
|
|
55
|
+
rdoc.rdoc_files.include('README*')
|
|
56
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
57
|
+
end
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.0.0
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
class PageAttachment < ActiveRecord::Base
|
|
2
|
+
acts_as_list :scope => :page_id
|
|
3
|
+
has_attachment :storage => :file_system,
|
|
4
|
+
:thumbnails => defined?(PAGE_ATTACHMENT_SIZES) && PAGE_ATTACHMENT_SIZES || {:icon => '50x50>'},
|
|
5
|
+
:max_size => 10.megabytes
|
|
6
|
+
validates_as_attachment
|
|
7
|
+
|
|
8
|
+
belongs_to :created_by,
|
|
9
|
+
:class_name => 'User',
|
|
10
|
+
:foreign_key => 'created_by'
|
|
11
|
+
belongs_to :updated_by,
|
|
12
|
+
:class_name => 'User',
|
|
13
|
+
:foreign_key => 'updated_by'
|
|
14
|
+
belongs_to :page
|
|
15
|
+
|
|
16
|
+
def short_filename(wanted_length = 15, suffix = ' ...')
|
|
17
|
+
(self.filename.length > wanted_length) ? (self.filename[0,(wanted_length - suffix.length)] + suffix) : self.filename
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def short_title(wanted_length = 15, suffix = ' ...')
|
|
21
|
+
(self.title.length > wanted_length) ? (self.title[0,(wanted_length - suffix.length)] + suffix) : self.title
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def short_description(wanted_length = 15, suffix = ' ...')
|
|
25
|
+
(self.description.length > wanted_length) ? (self.description[0,(wanted_length - suffix.length)] + suffix) : self.description
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module PageAttachmentAssociations
|
|
2
|
+
def self.included(base)
|
|
3
|
+
base.class_eval {
|
|
4
|
+
has_many :attachments,
|
|
5
|
+
:class_name => "PageAttachment",
|
|
6
|
+
:dependent => :destroy,
|
|
7
|
+
:order => 'position'
|
|
8
|
+
include InstanceMethods
|
|
9
|
+
accepts_nested_attributes_for :attachments, :allow_destroy => true
|
|
10
|
+
}
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
module InstanceMethods
|
|
14
|
+
# Currently recursive, but could be simplified with some SQL
|
|
15
|
+
def attachment(name)
|
|
16
|
+
att = attachments.find(:first, :conditions => ["filename LIKE ?", name.to_s])
|
|
17
|
+
att.blank? ? ((parent.attachment(name) if parent) or nil) : att
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
module PageAttachmentTags
|
|
2
|
+
include Radiant::Taggable
|
|
3
|
+
|
|
4
|
+
class TagError < StandardError; end
|
|
5
|
+
|
|
6
|
+
desc %{
|
|
7
|
+
The namespace for referencing page attachments/files. You may specify the 'name'
|
|
8
|
+
attribute (for the filename) on this tag for all contained tags to refer to that attachment.
|
|
9
|
+
Attachments can be inherited from parent pages.
|
|
10
|
+
|
|
11
|
+
*Usage*:
|
|
12
|
+
|
|
13
|
+
<pre><code><r:attachment name="file.txt">...</r:attachment></code></pre>
|
|
14
|
+
}
|
|
15
|
+
tag "attachment" do |tag|
|
|
16
|
+
page = tag.locals.page
|
|
17
|
+
tag.locals.attachment = page.attachment(tag.attr['name']) rescue nil if tag.attr['name']
|
|
18
|
+
tag.expand
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
desc %{
|
|
22
|
+
Renders the url or public filename of the attachment for use in links, stylesheets, etc.
|
|
23
|
+
The 'name' attribute is required on this tag or the parent tag. The optional 'size' attribute
|
|
24
|
+
applies only to images.
|
|
25
|
+
|
|
26
|
+
*Usage*:
|
|
27
|
+
|
|
28
|
+
<pre><code><r:attachment:url name="file.jpg" [size="icon"]/></code></pre>
|
|
29
|
+
}
|
|
30
|
+
tag "attachment:url" do |tag|
|
|
31
|
+
raise TagError, "'name' attribute required" unless name = tag.attr['name'] or tag.locals.attachment
|
|
32
|
+
page = tag.locals.page
|
|
33
|
+
size = tag.attr['size'] || nil
|
|
34
|
+
attachment = tag.locals.attachment || page.attachment(name)
|
|
35
|
+
attachment.public_filename(size)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
[:short_title,:short_description,:short_filename].each do |key|
|
|
39
|
+
desc %{
|
|
40
|
+
Renders the '#{key}' attribute of the attachment.
|
|
41
|
+
The 'name' attribute is required on this tag or the parent tag.
|
|
42
|
+
The optional 'length' attribute defines how many characters of the attribute to display. It defaults to 15 total characters, including the 'suffix'.
|
|
43
|
+
If the attribute exceeds 'length', 'suffix' says what to tag onto the back to show truncation. It defaults to ' ...'
|
|
44
|
+
|
|
45
|
+
*Usage*:
|
|
46
|
+
|
|
47
|
+
<pre><code><r:attachment:#{key} name="file.jpg" [length="number of characters"] [suffix="More . . ."]/></code></pre>
|
|
48
|
+
}
|
|
49
|
+
tag "attachment:#{key}" do |tag|
|
|
50
|
+
raise TagError, "'name' attribute required" unless name = tag.attr['name'] or tag.locals.attachment
|
|
51
|
+
page = tag.locals.page
|
|
52
|
+
attachment = tag.locals.attachment || page.attachment(name)
|
|
53
|
+
tlength = (tag.attr['length']) ? tag.attr['length'].to_i : 15
|
|
54
|
+
suffix = (tag.attr['suffix']) ? tag.attr['suffix'].to_s : ' ...'
|
|
55
|
+
attachment.send("#{key}",tlength,suffix)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
desc %{
|
|
60
|
+
Renders the 'size' attribute of the attachment.
|
|
61
|
+
The 'name' attribute is required on this tag or the parent tag. Returns bytes by default. Use the optional 'units' parameter to change the units this tag returns.
|
|
62
|
+
|
|
63
|
+
*Usage*:
|
|
64
|
+
|
|
65
|
+
<pre><code><r:attachment:size name="file.jpg" [units="bytes|kilobytes|megabytes|gigabytes"] /></code></pre>
|
|
66
|
+
}
|
|
67
|
+
tag "attachment:size" do |tag|
|
|
68
|
+
raise TagError, "'name' attribute required" unless name = tag.attr['name'] or tag.locals.attachment
|
|
69
|
+
page = tag.locals.page
|
|
70
|
+
attachment = tag.locals.attachment || page.attachment(name)
|
|
71
|
+
units = tag.attr['units'] || 'bytes'
|
|
72
|
+
valid_units = ['bytes','byte','kilobytes','kilobyte','megabytes','megabyte','gigabytes','gigabyte']
|
|
73
|
+
units = (valid_units.include?(units)) ? units : 'bytes'
|
|
74
|
+
return attachment.size if units == 'bytes'
|
|
75
|
+
sprintf('%.2f',(attachment.size.to_f / 1.send(units)))
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
[:content_type, :width, :height, :title, :description, :position, :filename].each do |key|
|
|
80
|
+
desc %{
|
|
81
|
+
Renders the '#{key}' attribute of the attachment.
|
|
82
|
+
The 'name' attribute is required on this tag or the parent tag. The optional 'size'
|
|
83
|
+
attributes applies only to images.
|
|
84
|
+
|
|
85
|
+
*Usage*:
|
|
86
|
+
|
|
87
|
+
<pre><code><r:attachment:#{key} name="file.jpg" [size="icon"]/></code></pre>
|
|
88
|
+
}
|
|
89
|
+
tag "attachment:#{key}" do |tag|
|
|
90
|
+
raise TagError, "'name' attribute required" unless name = tag.attr['name'] or tag.locals.attachment
|
|
91
|
+
page = tag.locals.page
|
|
92
|
+
attachment = tag.locals.attachment || page.attachment(name)
|
|
93
|
+
attachment.attributes["#{key}"]
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
desc %{
|
|
98
|
+
Renders the date the attachment was uploaded using the specified 'format' (Ruby's strftime syntax).
|
|
99
|
+
The 'name' attribute is required on this tag or the parent tag.
|
|
100
|
+
}
|
|
101
|
+
tag "attachment:date" do |tag|
|
|
102
|
+
raise TagError, "'name' attribute required" unless name = tag.attr['name'] or tag.locals.attachment
|
|
103
|
+
page = tag.locals.page
|
|
104
|
+
attachment = tag.locals.attachment || page.attachment(name)
|
|
105
|
+
format = tag.attr['format'] || "%F"
|
|
106
|
+
attachment.created_at.strftime(format)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
desc %{
|
|
110
|
+
Renders an image tag for the attachment (assuming it's an image).
|
|
111
|
+
The 'name' attribute is required on this tag or the parent tag.
|
|
112
|
+
Any other attributes will be added as HTML attributes to the rendered tag.
|
|
113
|
+
The optional 'size' attribute allows you to show the icon size of the image.
|
|
114
|
+
|
|
115
|
+
*Usage*:
|
|
116
|
+
|
|
117
|
+
<pre><code><r:attachment:image name="file.jpg" [size="icon"]/></code></pre>
|
|
118
|
+
|
|
119
|
+
}
|
|
120
|
+
tag "attachment:image" do |tag|
|
|
121
|
+
raise TagError, "'name' attribute required" unless name = tag.attr.delete('name') or tag.locals.attachment
|
|
122
|
+
page = tag.locals.page
|
|
123
|
+
attachment = tag.locals.attachment || page.attachment(name)
|
|
124
|
+
size = tag.attr['size'] || nil
|
|
125
|
+
raise TagError, "attachment is not an image." unless attachment.content_type.strip =~ /^image\//
|
|
126
|
+
filename = attachment.public_filename(size) rescue ""
|
|
127
|
+
attributes = tag.attr.inject([]){ |a,(k,v)| a << %{#{k}="#{v}"} }.join(" ").strip
|
|
128
|
+
%{<img src="#{filename}" #{attributes + " " unless attributes.empty?}/>}
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
desc %{
|
|
132
|
+
Renders a hyperlink to the attachment. The 'name' attribute is required on this tag or the parent tag.
|
|
133
|
+
You can use the 'label' attribute to specify the textual contents of the tag. Any other attributes
|
|
134
|
+
will be added as HTML attributes to the rendered tag. This tag works as both a singleton and a container.
|
|
135
|
+
Any contained content will be rendered inside the resulting link. The optional 'size' attribute applies only to images.
|
|
136
|
+
|
|
137
|
+
*Usage*:
|
|
138
|
+
|
|
139
|
+
<pre><code><r:attachment:link name="file.jpg" [size="thumbnail"]/></code></pre>
|
|
140
|
+
<pre><code><r:attachment:link name="file.jpg" [size="thumbnail"]> Some text in the link </r:attachment:link></code></pre>
|
|
141
|
+
}
|
|
142
|
+
tag "attachment:link" do |tag|
|
|
143
|
+
raise TagError, "'name' attribute required" unless name = tag.attr.delete('name') or tag.locals.attachment
|
|
144
|
+
page = tag.locals.page
|
|
145
|
+
attachment = tag.locals.attachment || page.attachment(name)
|
|
146
|
+
label = tag.attr.delete('label') || attachment.filename
|
|
147
|
+
size = tag.attr.delete('size') || nil
|
|
148
|
+
filename = attachment.public_filename(size) rescue ""
|
|
149
|
+
attributes = tag.attr.inject([]){ |a,(k,v)| a << %{#{k}="#{v}"} }.join(" ").strip
|
|
150
|
+
output = %{<a href="#{filename}"#{" " + attributes unless attributes.empty?}>}
|
|
151
|
+
output << (tag.double? ? tag.expand : label)
|
|
152
|
+
output << "</a>"
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
desc %{
|
|
156
|
+
Renders the name of who uploaded the attachment. The 'name' attribute is required on this tag or the parent tag.
|
|
157
|
+
|
|
158
|
+
*Usage*:
|
|
159
|
+
|
|
160
|
+
<pre><code><r:attachment:author name="file.jpg" /></code></pre>
|
|
161
|
+
}
|
|
162
|
+
tag "attachment:author" do |tag|
|
|
163
|
+
raise TagError, "'name' attribute required" unless name = tag.attr.delete('name') or tag.locals.attachment
|
|
164
|
+
page = tag.locals.page
|
|
165
|
+
attachment = tag.locals.attachment || page.attachment(name)
|
|
166
|
+
if attachment and author = attachment.created_by
|
|
167
|
+
author.name
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
desc %{
|
|
172
|
+
Iterates through all the attachments in the current page. The 'name' attribute is not required
|
|
173
|
+
on any nested attachment tags.
|
|
174
|
+
|
|
175
|
+
*Usage*:
|
|
176
|
+
|
|
177
|
+
<pre><code><r:attachment:each [order="asc|desc"] [by="filename|size|created_at|..."] [limit=0] [offset=0] [extensions="png|pdf|doc"]>
|
|
178
|
+
<r:link /> - <r:date>
|
|
179
|
+
</r:attachment:each></code></pre>
|
|
180
|
+
}
|
|
181
|
+
tag "attachment:each" do |tag|
|
|
182
|
+
page = tag.locals.page
|
|
183
|
+
|
|
184
|
+
returning String.new do |output|
|
|
185
|
+
page.attachments.find(:all, attachments_find_options(tag)).each do |att|
|
|
186
|
+
tag.locals.attachment = att
|
|
187
|
+
output << tag.expand
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
desc %{
|
|
193
|
+
Renders the contained elements only if the current contextual page has one or
|
|
194
|
+
more attachments. The @min_count@ attribute specifies the minimum number of required
|
|
195
|
+
attachments. You can also filter by extensions with the @extensions@ attribute.
|
|
196
|
+
|
|
197
|
+
*Usage:*
|
|
198
|
+
<pre><code><r:if_attachments [min_count="n"] [extensions="doc|pdf"]>...</r:if_attachments></code></pre>
|
|
199
|
+
}
|
|
200
|
+
tag "if_attachments" do |tag|
|
|
201
|
+
count = tag.attr['min_count'] && tag.attr['min_count'].to_i || 0
|
|
202
|
+
attachments = tag.locals.page.attachments.count(:conditions => attachments_find_options(tag)[:conditions])
|
|
203
|
+
tag.expand if attachments >= count
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
desc %{
|
|
207
|
+
Renders the contained elements only if the current contextual page has no attachments.
|
|
208
|
+
|
|
209
|
+
*Usage:*
|
|
210
|
+
<pre><code><r:unless_attachments>...</r:unless_attachments></code></pre>
|
|
211
|
+
}
|
|
212
|
+
tag "unless_attachments" do |tag|
|
|
213
|
+
count = tag.attr[''].to_i
|
|
214
|
+
attachments = tag.locals.page.attachments.count(:conditions => attachments_find_options(tag)[:conditions])
|
|
215
|
+
tag.expand if attachments == 0
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
desc %{
|
|
219
|
+
Renders the 'extension' virtual attribute of the attachment, extracted from filename.
|
|
220
|
+
|
|
221
|
+
*Usage*:
|
|
222
|
+
|
|
223
|
+
<pre><code>
|
|
224
|
+
<ul>
|
|
225
|
+
<r:attachment:each extensions="doc|pdf">
|
|
226
|
+
<li class="<r:extension/>">
|
|
227
|
+
<r:link/>
|
|
228
|
+
</li>
|
|
229
|
+
</r:attachment:each>
|
|
230
|
+
</ul>
|
|
231
|
+
</code></pre>
|
|
232
|
+
}
|
|
233
|
+
tag "attachment:extension" do |tag|
|
|
234
|
+
raise TagError, "must be nested inside an attachment or attachment:each tag" unless tag.locals.attachment
|
|
235
|
+
attachment = tag.locals.attachment
|
|
236
|
+
attachment.filename[/\.(\w+)$/, 1]
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
private
|
|
240
|
+
def attachments_find_options(tag)
|
|
241
|
+
attr = tag.attr.symbolize_keys
|
|
242
|
+
|
|
243
|
+
extensions = attr[:extensions] && attr[:extensions].split('|') || []
|
|
244
|
+
conditions = unless extensions.blank?
|
|
245
|
+
[ extensions.map { |ext| "page_attachments.filename LIKE ?"}.join(' OR '),
|
|
246
|
+
*extensions.map { |ext| "%.#{ext}" } ]
|
|
247
|
+
else
|
|
248
|
+
nil
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
by = attr[:by] || "position"
|
|
252
|
+
order = attr[:order] || "asc"
|
|
253
|
+
|
|
254
|
+
options = {
|
|
255
|
+
:order => "#{by} #{order}",
|
|
256
|
+
:offset => attr[:offset] || nil,
|
|
257
|
+
:limit => attr[:limit] || (attr[:offset] ? 9999 : nil),
|
|
258
|
+
:conditions => conditions
|
|
259
|
+
}
|
|
260
|
+
end
|
|
261
|
+
end
|