Index: app/helpers/download_helper.rb =================================================================== --- app/helpers/download_helper.rb (revision 16) +++ app/helpers/download_helper.rb (working copy) @@ -3,10 +3,11 @@ def download_button(project, download = nil, options = {}) version = latest_version(project) if version && (options[:force] || version.attachments.any? || (download && download.file_id.to_i < 0)) - return render(:partial => 'download/button', - :locals => { :label => download_label(version, download), - :package => download_package(version, download), - :link => download_link(version, download) }) + render(:partial => 'download/button', + :locals => { :label => download_label(version, download), + :package => download_package(version, download), + :link => download_link(version, download), + :style => options[:style] }) end end @@ -46,24 +47,24 @@ def download_label(version, download = nil) if download && download.file_id.to_i < 0 - download.label.present? ? h(download.label) : l(:locale_download) + download.label.present? ? download.label : t(:locale_download) elsif version.attachments_visible? - download && download.label.present? ? h(download.label) : l(:locale_download) + download && download.label.present? ? download.label : t(:locale_download) else - l(:locale_authorize) + t(:locale_authorize) end end def download_package(version, download = nil) package = '' if download && download.file_id.to_i < 0 - package = download.package.present? ? h(download.package) : h(version.project.name) - package += ' ' + h(version.name) if download.include_version? + package = download.package.present? ? download.package : version.project.name + package += ' ' + version.name if download.include_version? elsif version.attachments_visible? - package = download && download.package.present? ? h(download.package) : h(version.project.name) - package += ' ' + h(version.name) if !download || download.include_version? + package = download && download.package.present? ? download.package : version.project.name + package += ' ' + version.name if !download || download.include_version? else - package = l(:locale_to_download) + package = t(:locale_to_download) end package end Index: app/views/download/_button.rhtml =================================================================== --- app/views/download/_button.rhtml (revision 16) +++ app/views/download/_button.rhtml (working copy) @@ -1,4 +1,4 @@ - + <%= h(label) %> <%= h(package) %> Index: app/views/download/_tag.rhtml =================================================================== --- app/views/download/_tag.rhtml (revision 0) +++ app/views/download/_tag.rhtml (revision 0) @@ -0,0 +1,4 @@ +
+ <%= download_button(project, download, :style => button_style) %> +
+
Index: app/views/download/_sidebar.rhtml =================================================================== --- app/views/download/_sidebar.rhtml (revision 16) +++ app/views/download/_sidebar.rhtml (working copy) @@ -5,7 +5,10 @@ controller.class.name == 'ActivitiesController' || controller.class.name == 'VersionsController' || controller.class.name == 'WikiController' %> -

<%= download_button(@project, @download) %>

+
+ <%= download_button(@project, @download) %> +
+
<% end %> <% end %> <% end %> Index: assets/stylesheets/download.css =================================================================== --- assets/stylesheets/download.css (revision 16) +++ assets/stylesheets/download.css (working copy) @@ -1,5 +1,6 @@ a.download { display: inline-block; + float: left; font-size: 14px; font-weight: bold; background-color: #67b243; @@ -7,26 +8,47 @@ background-position: left bottom; background-repeat: repeat-x; border: 1px solid #288c44; - color: #f8f8f8; padding: 2px 20px 2px 0; text-align: center; text-decoration: none; border-radius: 5px; -moz-border-radius: 5px; } -a.download span.icon-download { +a.download:hover { + text-decoration: none; +} +a.download:link { + text-decoration: none; +} +a.download:visited { + text-decoration: none; +} +#sidebar a.download:hover { + text-decoration: none; +} +#sidebar a.download:link { + text-decoration: none; +} +#sidebar a.download:visited { + text-decoration: none; +} +a.download .icon-download { + display: block; + color: #f8f8f8; background-image: url(../images/arrow.gif); background-position: 7px center; background-repeat: no-repeat; padding-left: 30px; - display: block; } a.download .version { display: block; - font-size: 10px; + font-size: 70%; font-weight: normal; margin-top: -3px; } +a.download .clear { + clear: both; +} #download-button { margin: 0.5em 0.5em 0 0; float: right; Index: init.rb =================================================================== --- init.rb (revision 16) +++ init.rb (working copy) @@ -29,7 +29,80 @@ author_url 'http://www.andriylesyuk.com/' description 'Adds Download button to projects.' url 'http://projects.andriylesyuk.com/projects/redmine-download' - version '0.0.2' + version '0.0.3' permission :manage_download_button, { :projects => :settings, :download => :edit }, :require => :member + + begin + + class DownloadButtonTag < ChiliProject::Liquid::Tags::Tag + include DownloadMacroHelper + + def initialize(tag_name, markup, tokens) + tag_args = markup.strip.gsub(/^[("']|["')]$/, '') + if tag_args.present? + @args = tag_args.split(',') + else + @args = [] + end + super + end + + def render(context) + # render context + @project = Project.find(context['project'].identifier ) if context['project'].present? + @view = context.registers[:view] + # parse arguments + attributes, options = extract_download_options(@args) + # find project + if attributes[:project_id] + @project = Project.find_by_id(attributes[:project_id]) + raise "invalid project ID: #{h(attributes[:project_id])}" unless @project + elsif @project.present? + attributes[:project_id] = @project.id + else + raise "download button tag can only be used in project context" + end + # instantiate new (temporary) download button + download = DownloadButton.new(attributes) + raise "Failed to instantiate download button" unless download + # render download button + @view.render(:partial => "download/tag", :locals => { :project => @project, + :download => download, + :container_style => to_container_style(options), + :button_style => to_button_style(options) }) + end + + end + + ChiliProject::Liquid::Tags::register_tag('download_button', DownloadButtonTag, :html => true) + + rescue + + Redmine::WikiFormatting::Macros.register do + desc "Inserts Download button in Wiki pages" + macro :download_button do |obj, args| + # parse arguments + attributes, options = DownloadMacroHelper.extract_download_options(args) + # find project + if attributes[:project_id] + @project = Project.find_by_id(attributes[:project_id]) + raise "invalid project ID: #{h(attributes[:project_id])}" unless @project + elsif @project.present? + attributes[:project_id] = @project.id + else + raise "download button macro can only be used in project context" + end + # instantiate new (temporary) download button + download = DownloadButton.new(attributes) + raise "Failed to instantiate download button" unless download + # render download button + render(:partial => "download/tag", :locals => { :project => @project, + :download => download, + :container_style => DownloadMacroHelper.to_container_style(options), + :button_style => DownloadMacroHelper.to_button_style(options) }) + end + end + + end end Index: lib/download_macro_helper.rb =================================================================== --- lib/download_macro_helper.rb (revision 0) +++ lib/download_macro_helper.rb (revision 0) @@ -0,0 +1,62 @@ + +module DownloadMacroHelper + module_function + + def extract_macro_options(args, *keys) + options = {} + while args.last.to_s.strip =~ %r{^([^=]+)\=(.+)$} && keys.include?($1.downcase.to_sym) + options[$1.downcase.to_sym] = $2 + args.pop + end + return [args, options] + end + + def extract_download_options(args) + # parse arguments + args, options = extract_macro_options(args, :float, :width, + :margin, :margin_top, :margin_right, + :margin_bottom, :margin_left, :font_size) + args, attributes = extract_macro_options(args, :project_id, :label, + :package, :include_version, :file_id, :url) + # throw error if invalid arguments given + raise "invalid argument(s) #{h(args.join(', '))}" if args.length > 0 + # compose style of download button container + container_style = [] + container_style.push("float: #{options[:float]}") if options[:float] + container_style.push("margin: #{options[:margin]}") if options[:margin] + container_style.push("margin-top: #{options[:margin_top]}") if options[:margin_top] + container_style.push("margin-right: #{options[:margin_right]}") if options[:margin_right] + container_style.push("margin-bottom: #{options[:margin_bottom]}") if options[:margin_bottom] + container_style.push("margin-left: #{options[:margin_left]}") if options[:margin_left] + container_style = container_style.join('; ') + # compase style of download button itself + button_style = [] + button_style.push("width: #{options[:width]}") if options[:width] + button_style.push("font-size: #{options[:font_size]}") if options[:font_size] + button_style = button_style.join('; ') + # set default attributes + attributes[:file_id] = -1 if attributes[:url] + attributes[:disabled] = false + + return [attributes, options] + end + + def to_container_style(options) + container_style = [] + container_style.push("float: #{options[:float]}") if options[:float] + container_style.push("margin: #{options[:margin]}") if options[:margin] + container_style.push("margin-top: #{options[:margin_top]}") if options[:margin_top] + container_style.push("margin-right: #{options[:margin_right]}") if options[:margin_right] + container_style.push("margin-bottom: #{options[:margin_bottom]}") if options[:margin_bottom] + container_style.push("margin-left: #{options[:margin_left]}") if options[:margin_left] + return container_style.join('; ') + end + + def to_button_style(options) + button_style = [] + button_style.push("width: #{options[:width]}") if options[:width] + button_style.push("font-size: #{options[:font_size]}") if options[:font_size] + return button_style.join('; ') + end + +end