Ticket #630: page_attachment_tags.rb

File page_attachment_tags.rb, 6.2 kB (added by adamski, 6 months ago)

page_attachment_tags.rb

Line 
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   [:content_type, :size, :width, :height].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.  The optional 'size'
42       attributes applies only to images.
43       
44     *Usage*:
45     
46     <pre><code><r:attachment:#{key} name="file.jpg" [size="icon"]/></code></pre>
47     }
48     tag "attachment:#{key}" do |tag|
49       raise TagError, "'name' attribute required" unless name = tag.attr['name'] or tag.locals.attachment
50       page = tag.locals.page
51       attachment = tag.locals.attachment || page.attachment(name)
52       attachment.attributes["#{key}"]
53     end
54   end
55  
56   desc %{
57     Renders the date the attachment was uploaded using the specified `format' (Ruby's strftime syntax).
58     The 'name' attribute is required on this tag or the parent tag.
59   }
60   tag "attachment:date" do |tag|
61     raise TagError, "'name' attribute required" unless name = tag.attr['name'] or tag.locals.attachment
62     page = tag.locals.page
63     attachment = tag.locals.attachment || page.attachment(name)
64     format = tag.attr['format'] || "%F" 
65     attachment.created_at.strftime(format)
66   end
67  
68   desc %{
69     Renders an image tag for the attachment (assuming it's an image).
70     The 'name' attribute is required on this tag or the parent tag.
71     Any other attributes will be added as HTML attributes to the rendered tag.
72     The optional 'size' attribute allows you to show the icon size of the image.
73
74     *Usage*:
75     
76     <pre><code><r:attachment:image name="file.jpg" [size="icon"]/></code></pre>
77
78     }
79   tag "attachment:image" do |tag|
80     raise TagError, "'name' attribute required" unless name = tag.attr.delete('name') or tag.locals.attachment
81     page = tag.locals.page
82     attachment = tag.locals.attachment || page.attachment(name)
83     size = tag.attr['size'] || nil
84     raise TagError, "attachment is not an image." unless attachment.content_type.strip =~ /^image\//
85     filename = attachment.public_filename(size) rescue ""
86     attributes = tag.attr.inject([]){ |a,(k,v)| a << %{#{k}="#{v}"} }.join(" ").strip
87     %{<img src="#{filename}" #{attributes + " " unless attributes.empty?}/>}
88   end
89  
90   desc %{
91     Renders a hyperlink to the attachment. The 'name' attribute is required on this tag or the parent tag.
92     You can use the 'label' attribute to specify the textual contents of the tag.  Any other attributes
93     will be added as HTML attributes to the rendered tag.  This tag works as both a singleton and a container.
94     Any contained content will be rendered inside the resulting link.  The optional 'size' attribute applies only to images.
95
96     *Usage*:
97     
98     <pre><code><r:attachment:link name="file.jpg" [size="thumbnail"]/></code></pre>
99     <pre><code><r:attachment:link name="file.jpg" [size="thumbnail"]> Some text in the link </r:attachment:link></code></pre>
100   }
101   tag "attachment:link" do |tag|
102     raise TagError, "'name' attribute required" unless name = tag.attr.delete('name') or tag.locals.attachment
103     page = tag.locals.page
104     attachment = tag.locals.attachment || page.attachment(name)
105     label = tag.attr.delete('label') || attachment.filename
106     size = tag.attr.delete('size') || nil
107     filename = attachment.public_filename(size) rescue ""
108     attributes = tag.attr.inject([]){ |a,(k,v)| a << %{#{k}="#{v}"} }.join(" ").strip
109     output = %{<a href="#{filename}"#{" " + attributes unless attributes.empty?}>}
110     output << (tag.double? ? tag.expand : label)
111     output << "</a>"
112   end
113  
114   desc %{
115     Renders the name of who uploaded the attachment. The 'name' attribute is required on this tag or the parent tag.
116     
117     *Usage*:
118     
119     <pre><code><r:attachment:author name="file.jpg" /></code></pre>
120   }
121   tag "attachment:author" do |tag|
122     raise TagError, "'name' attribute required" unless name = tag.attr.delete('name') or tag.locals.attachment
123     page = tag.locals.page
124     attachment = tag.locals.attachment || page.attachment(name)
125     if attachment and author = attachment.created_by
126       author.name
127     end
128   end
129  
130   desc %{
131     Iterates through all the attachments in the current page.  The 'name' attribute is not required
132     on any nested attachment tags.
133     
134     *Usage*:
135     
136     <pre><code><r:attachment:each [order="asc|desc"] [by="filename|size|created_at|..."] [limit="value"] [offset="value"]>
137         <r:link /> - <r:date>
138     </r:attachment:each></pre></code>
139   }
140   tag "attachment:each" do |tag|
141     page = tag.locals.page
142         order = tag.attr["order"] || "asc"
143     by = tag.attr["by"] || "id"
144     limit = tag.attr["limit"] || 50
145     offset = tag.attr["offset"] || 0
146     returning String.new do |output|
147       page.attachments.find(:all, :limit => limit, :offset => offset, :order => [by, order].join(" ")).each do |att|
148         tag.locals.attachment = att
149         output << tag.expand
150       end
151     end
152   end 
153 end