<%= 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