Index: app/helpers/download_helper.rb =================================================================== --- app/helpers/download_helper.rb (revision 16) +++ app/helpers/download_helper.rb (working copy) @@ -6,7 +6,8 @@ return render(:partial => 'download/button', :locals => { :label => download_label(version, download), :package => download_package(version, download), - :link => download_link(version, download) }) + :link => download_link(version, download), + :style => options[:style] }) end end Index: app/views/download/_button.rhtml =================================================================== --- app/views/download/_button.rhtml (revision 16) +++ app/views/download/_button.rhtml (working copy) @@ -1,6 +1,7 @@ - + <%= 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) @@ -7,14 +7,15 @@ 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; + float: left; /* required in particular for ChiliProject 3.0 theme */ } -a.download span.icon-download { +a.download .icon-download { + color: #f8f8f8; background-image: url(../images/arrow.gif); background-position: 7px center; background-repeat: no-repeat; @@ -23,10 +24,36 @@ } a.download .version { display: block; - font-size: 10px; + font-size: 70%; font-weight: normal; margin-top: -3px; } +/* force no text decoration for button */ +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 .clear { + clear: both; +} +.download-button .clear { + clear: both; +} +/* ID used for project settings preview */ #download-button { margin: 0.5em 0.5em 0 0; float: right; Index: init.rb =================================================================== --- init.rb (revision 16) +++ init.rb (working copy) @@ -32,4 +32,77 @@ version '0.0.2' 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