I'm looking for a part-time remote job.

Hire me


I'm the author of:

Mastering Redmine is a comprehensive guide with tips, tricks and best practices, and an easy-to-learn structure.

Check the book's project or

Buy the book

Social pages of the book:

By buying this book you also donate to Redmine (see this page).


Follow me:

compatibility_with_chili_project_and_addition_of_wiki_macro_or_liquid_tag_for_chili_project_3_0.patch

Patch for r16. Implements this feature and fixes #1929. - Andreas Schuh, 05 Jan 2012 19:28

Download (12.8 KB)

View differences:

app/helpers/download_helper.rb (working copy)
3 3
    def download_button(project, download = nil, options = {})
4 4
        version = latest_version(project)
5 5
        if version && (options[:force] || version.attachments.any? || (download && download.file_id.to_i < 0))
6
            return render(:partial => 'download/button',
7
                          :locals  => { :label   => download_label(version, download),
8
                                        :package => download_package(version, download),
9
                                        :link    => download_link(version, download) })
6
            render(:partial => 'download/button',
7
                   :locals  => { :label   => download_label(version, download),
8
                                 :package => download_package(version, download),
9
                                 :link    => download_link(version, download),
10
                                 :style   => options[:style] })
10 11
        end
11 12
    end
12 13

  
......
46 47

  
47 48
    def download_label(version, download = nil)
48 49
        if download && download.file_id.to_i < 0
49
            download.label.present? ? h(download.label) : l(:locale_download)
50
            download.label.present? ? download.label : t(:locale_download)
50 51
        elsif version.attachments_visible?
51
            download && download.label.present? ? h(download.label) : l(:locale_download)
52
            download && download.label.present? ? download.label : t(:locale_download)
52 53
        else
53
            l(:locale_authorize)
54
            t(:locale_authorize)
54 55
        end
55 56
    end
56 57

  
57 58
    def download_package(version, download = nil)
58 59
        package = ''
59 60
        if download && download.file_id.to_i < 0
60
            package = download.package.present? ? h(download.package) : h(version.project.name)
61
            package += ' ' + h(version.name) if download.include_version?
61
            package = download.package.present? ? download.package : version.project.name
62
            package += ' ' + version.name if download.include_version?
62 63
        elsif version.attachments_visible?
63
            package = download && download.package.present? ? h(download.package) : h(version.project.name)
64
            package += ' ' + h(version.name) if !download || download.include_version?
64
            package = download && download.package.present? ? download.package : version.project.name
65
            package += ' ' + version.name if !download || download.include_version?
65 66
        else
66
            package = l(:locale_to_download)
67
            package = t(:locale_to_download)
67 68
        end
68 69
        package
69 70
    end
app/views/download/_button.rhtml (working copy)
1
<a href="<%= h(link) %>" class="download">
1
<a href="<%= h(link) %>" class="download" style="<%= h(style) %>">
2 2
  <span class="icon-download">
3 3
    <%= h(label) %>
4 4
    <span class="version"><%= h(package) %></span>
app/views/download/_tag.rhtml (revision 0)
1
<div class="download-button" style="<%= h(container_style) %>">
2
  <%= download_button(project, download, :style => button_style) %>
3
  <div class="clear"></div>
4
</div>
app/views/download/_sidebar.rhtml (working copy)
5 5
          controller.class.name == 'ActivitiesController' ||
6 6
          controller.class.name == 'VersionsController' ||
7 7
          controller.class.name == 'WikiController' %>
8
      <p><%= download_button(@project, @download) %></p>
8
      <div class="download-button">
9
        <%= download_button(@project, @download) %>
10
      </div>
11
      <div class="clear"></div>
9 12
    <% end %>
10 13
  <% end %>
11 14
<% end %>
assets/stylesheets/download.css (working copy)
1 1
a.download {
2 2
    display: inline-block;
3
    float: left;
3 4
    font-size: 14px;
4 5
    font-weight: bold;
5 6
    background-color: #67b243;
......
7 8
    background-position: left bottom;
8 9
    background-repeat: repeat-x;
9 10
    border: 1px solid #288c44;
10
    color: #f8f8f8;
11 11
    padding: 2px 20px 2px 0;
12 12
    text-align: center;
13 13
    text-decoration: none;
14 14
    border-radius: 5px;
15 15
    -moz-border-radius: 5px;
16 16
}
17
a.download span.icon-download {
17
a.download:hover {
18
    text-decoration: none;
19
}
20
a.download:link {
21
    text-decoration: none;
22
}
23
a.download:visited {
24
    text-decoration: none;
25
}
26
#sidebar a.download:hover {
27
    text-decoration: none;
28
}
29
#sidebar a.download:link {
30
    text-decoration: none;
31
}
32
#sidebar a.download:visited {
33
    text-decoration: none;
34
}
35
a.download .icon-download {
36
    display: block;
37
    color: #f8f8f8;
18 38
    background-image: url(../images/arrow.gif);
19 39
    background-position: 7px center;
20 40
    background-repeat: no-repeat;
21 41
    padding-left: 30px;
22
    display: block;
23 42
}
24 43
a.download .version {
25 44
    display: block;
26
    font-size: 10px;
45
    font-size: 70%;
27 46
    font-weight: normal;
28 47
    margin-top: -3px;
29 48
}
49
a.download .clear {
50
    clear: both;
51
}
30 52
#download-button {
31 53
    margin: 0.5em 0.5em 0 0;
32 54
    float: right;
init.rb (working copy)
29 29
    author_url 'http://www.andriylesyuk.com/'
30 30
    description 'Adds Download button to projects.'
31 31
    url 'http://projects.andriylesyuk.com/projects/redmine-download'
32
    version '0.0.2'
32
    version '0.0.3'
33 33

  
34 34
    permission :manage_download_button, { :projects => :settings, :download => :edit }, :require => :member
35

  
36
    begin
37

  
38
        class DownloadButtonTag < ChiliProject::Liquid::Tags::Tag
39
            include DownloadMacroHelper
40

  
41
            def initialize(tag_name, markup, tokens)
42
                tag_args = markup.strip.gsub(/^[("']|["')]$/, '')
43
                if tag_args.present?
44
                    @args = tag_args.split(',')
45
                else
46
                    @args = []
47
                end
48
                super
49
            end
50

  
51
            def render(context)
52
                # render context
53
                @project = Project.find(context['project'].identifier ) if context['project'].present?
54
                @view    = context.registers[:view]
55
                # parse arguments
56
                attributes, options = extract_download_options(@args)
57
                # find project
58
                if attributes[:project_id]
59
                    @project = Project.find_by_id(attributes[:project_id])
60
                    raise "invalid project ID: #{h(attributes[:project_id])}" unless @project
61
                elsif @project.present?
62
                    attributes[:project_id] = @project.id
63
                else
64
                    raise "download button tag can only be used in project context"
65
                end
66
                # instantiate new (temporary) download button
67
                download = DownloadButton.new(attributes)
68
                raise "Failed to instantiate download button" unless download
69
                # render download button
70
                @view.render(:partial => "download/tag", :locals => { :project         => @project,
71
                                                                      :download        => download,
72
                                                                      :container_style => to_container_style(options),
73
                                                                      :button_style    => to_button_style(options) })
74
            end
75

  
76
        end
77

  
78
        ChiliProject::Liquid::Tags::register_tag('download_button', DownloadButtonTag, :html => true)
79

  
80
    rescue
81

  
82
        Redmine::WikiFormatting::Macros.register do
83
            desc "Inserts Download button in Wiki pages"
84
            macro :download_button do |obj, args|
85
                # parse arguments
86
                attributes, options = DownloadMacroHelper.extract_download_options(args)
87
                # find project
88
                if attributes[:project_id]
89
                    @project = Project.find_by_id(attributes[:project_id])
90
                    raise "invalid project ID: #{h(attributes[:project_id])}" unless @project
91
                elsif @project.present?
92
                    attributes[:project_id] = @project.id
93
                else
94
                    raise "download button macro can only be used in project context"
95
                end
96
                # instantiate new (temporary) download button
97
                download = DownloadButton.new(attributes)
98
                raise "Failed to instantiate download button" unless download
99
                # render download button
100
                render(:partial => "download/tag", :locals => { :project         => @project,
101
                                                                :download        => download,
102
                                                                :container_style => DownloadMacroHelper.to_container_style(options),
103
                                                                :button_style    => DownloadMacroHelper.to_button_style(options) })
104
            end
105
        end
106

  
107
    end
35 108
end
lib/download_macro_helper.rb (revision 0)
1

  
2
module DownloadMacroHelper
3
    module_function
4

  
5
    def extract_macro_options(args, *keys)
6
        options = {}
7
        while args.last.to_s.strip =~ %r{^([^=]+)\=(.+)$} && keys.include?($1.downcase.to_sym)
8
            options[$1.downcase.to_sym] = $2
9
            args.pop
10
        end
11
        return [args, options]
12
    end
13

  
14
    def extract_download_options(args)
15
        # parse arguments
16
        args, options = extract_macro_options(args, :float, :width,
17
                                :margin, :margin_top, :margin_right,
18
                                :margin_bottom, :margin_left, :font_size)
19
        args, attributes = extract_macro_options(args, :project_id, :label,
20
                                   :package, :include_version, :file_id, :url)
21
        # throw error if invalid arguments given
22
        raise "invalid argument(s) #{h(args.join(', '))}" if args.length > 0
23
        # compose style of download button container
24
        container_style = []
25
        container_style.push("float:         #{options[:float]}")         if options[:float]
26
        container_style.push("margin:        #{options[:margin]}")        if options[:margin]
27
        container_style.push("margin-top:    #{options[:margin_top]}")    if options[:margin_top]
28
        container_style.push("margin-right:  #{options[:margin_right]}")  if options[:margin_right]
29
        container_style.push("margin-bottom: #{options[:margin_bottom]}") if options[:margin_bottom]
30
        container_style.push("margin-left:   #{options[:margin_left]}")   if options[:margin_left]
31
        container_style = container_style.join('; ')
32
        # compase style of download button itself
33
        button_style = []
34
        button_style.push("width: #{options[:width]}") if options[:width]
35
        button_style.push("font-size: #{options[:font_size]}") if options[:font_size]
36
        button_style = button_style.join('; ')
37
        # set default attributes
38
        attributes[:file_id] = -1 if attributes[:url]
39
        attributes[:disabled] = false
40

  
41
        return [attributes, options]
42
    end
43

  
44
    def to_container_style(options)
45
        container_style = []
46
        container_style.push("float:         #{options[:float]}")         if options[:float]
47
        container_style.push("margin:        #{options[:margin]}")        if options[:margin]
48
        container_style.push("margin-top:    #{options[:margin_top]}")    if options[:margin_top]
49
        container_style.push("margin-right:  #{options[:margin_right]}")  if options[:margin_right]
50
        container_style.push("margin-bottom: #{options[:margin_bottom]}") if options[:margin_bottom]
51
        container_style.push("margin-left:   #{options[:margin_left]}")   if options[:margin_left]
52
        return container_style.join('; ')
53
    end
54

  
55
    def to_button_style(options)
56
        button_style = []
57
        button_style.push("width: #{options[:width]}") if options[:width]
58
        button_style.push("font-size: #{options[:font_size]}") if options[:font_size]
59
        return button_style.join('; ')
60
    end
61

  
62
end
Terms of use | Privacy policy