Project

General

Profile

Collapsing index page in wiki

Added by Igor Conung vic almost 15 years ago

Good day all!
First of all, I want to apologize for my bad english.

(My native language is russian, and this post on russian is here)

We begin to use Redmine in our project about 3 weeks ago. In that time we wrote some wiki-pages and our page index has very big and inconvenient(I'm not sure in this word =)).

I decide make our page index be collapsable. My expirience in Redmine and RubyOnRails is very small, and I understand that my decision in not "clear" and professional, but it works.

What I do:

1. I change file redmine_root/app/views/wiki/special_page_index.rhtml

string

<%= render_page_hierarchy(@pages_by_parent_id, nil) %>

I replace with

<ul class="root_item">Оглавление
<%= render_page_hierarchy(@pages_by_parent_id, nil, true) %>
</ul>

2. Change file /app/views/layots/base.rhtml

text

<%= call_hook :view_layouts_base_html_head %>
<!-- page specific tags -->
<%= yield :header_tags -%>
</head>

I replace with

<%= call_hook :view_layouts_base_html_head %>
<!-- page specific tags -->
<%= yield :header_tags -%>
<style type="text/css">
<!--
li.root_item {list-style-type: none;list-style-image: url();}
li.open_item {list-style-image: url(FULL_PATH_TO_REDMINE/images/minus.gif);}
li.close_item {list-style-image: url(FULL_PATH_TO_REDMINE/images/plus.gif);}
li.list_item {list-style-type: none;list-style-image: url(FULL_PATH_TO_REDMINE/images/empty.gif);}
ul.open_list {cursor:pointer;display:block;list-style-type: none;list-style-image: none;}
ul.close_list {cursor:pointer;display:none;list-style-type: none;list-style-image: none;}
-->
</style>
<script language="javascript1.4" type="text/javascript">
    var DOM;
    var Opera;
    var IE;
    var Firefox;
  function do_some(src, evt) {
    if (!Firefox) {
        cls = src.children[1].className;
        if (cls=='open_list') {
          src.children[1].className = 'close_list';
          src.className = 'close_item';
        } else {
          src.children[1].className = 'open_list';
          src.className = 'open_item';
        }
        window.event.cancelBubble = true;
    } else {
        if (evt.eventPhase!=3) {
            cls = src.className;
             if (cls=='open_item') {
              src.childNodes[3].className = 'close_list';
              src.className = 'close_item';
            } else {
              src.childNodes[3].className = 'open_list';
              src.className = 'open_item';
            }
        }
    }
  }
  function Check() {
    if (!Firefox) {
      window.event.cancelBubble = true;
    }
  }
DOM = document.getElementById;
Opera = window.opera && DOM;
IE = document.all && !Opera;
Firefox = navigator.userAgent.indexOf("Firefox") >= 0;
</script>
</head>

3. Change file /app/helpers/application_helper.rb

text

  def render_page_hierarchy(pages, node=nil)
    content = ''
    if pages[node]
      content << "<ul class=\"pages-hierarchy\">\n" 
      pages[node].each do |page|
        content << "<li>" 
        content << link_to(h(page.pretty_title), {:controller => 'wiki', :action => 'index', :id => page.project, :page => page.title},
                           :title => (page.respond_to?(:updated_on) ? l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)) : nil))
        content << "\n" + render_page_hierarchy(pages, page.id) if pages[page.id]
        content << "</li>\n" 
      end
      content << "</ul>\n" 
    end
    content
  end

I replace with

  def render_page_hierarchy(pages, node=nil, first=nil)
     content = ''
     if pages[node]
       if first 
         css_class = "open" 
       else
         css_class = "close" 
       end
       content << "<ul class=\""+css_class+"_list\" onClick=\"Check();\">\n" 
       pages[node].each do |page|
         js = "" 
         if pages[page.id]
           css_class = "close" 
           js = "onClick=\"do_some(this, event);\"" 
           content << "<li class=\""+css_class+"_item\""+js+" >\n" 
           content << h(page.pretty_title)+"&nbsp;" 
           content << link_to("<b>=><img src=\"FULL_PATH_TO_REDMINE/images/external.png\"></b>", {:controller => 'wiki', :action => 'index', :id => page.project, :page => page.title},
                              :title => (page.respond_to?(:updated_on) ? l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)) : nil))
           content << "\n"+render_page_hierarchy(pages, page.id)
         else
           css_class = "list" 
           content << "<li class=\""+css_class+"_item\""+js+" >\n" 
           content << link_to(h(page.pretty_title)+"&nbsp;", {:controller => 'wiki', :action => 'index', :id => page.project, :page => page.title},
                              :title => (page.respond_to?(:updated_on) ? l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)) : nil))
         end
         content << "</li> \n" 
       end
       content << "</ul> \n" 
     end
     content
  end

4. Add files plus.gif, minus.gif, empty.gif to directory /public/images

(empty.gif is a 1 transparent pixel)
- minus.gif
- plus.gif

What I have done:
1. Collapsable page index
2. Whole name of element will be a link for elements without childs elements
3. Special text (=>) near element will be a link for elements with childs elements

That it is not pleasant to me:
1. My code is not perect. But now I can better =)
2. FULL_PATH_TO_REDMINE - is ABSOLUTLY addres of a server with redmine (with "http://")
3. AND MAIN. If I will update my redmine I will lost all my changes. How can I make plugin for it?

And screenshots of this: