Hatena::Grouprmind

技術的な説明

技術的な説明

Ruby on Rails

ReviewableMindは Ruby on Rails (1.2ベース) 及び、以下のソフトを利用して開発しています。

ReviewableMind自身は、Ruby's ライセンスのオープンソースソフトウエアです。

開発サイト等は準備中ですが、とりあえず、下記サイトでソースを公開します。

Amrita2

ReviewableMindでは、テンプレートエンジンとしてAmrita2を使用しています。

Amrita2もReviewableMindと同様に、オープンソースソフトウエアとして公開に向けて準備中です。

たとえば、タスクの一覧は次のようなテンプレートとHelper moduleによって表示しています。

  << ?[ task_list.size == 0 ] <
    (There is no task in  [<<:list_name>>]  now)

  << ?[ task_list.size > 0 ] <
    <<table<
      <<tr<
        <<th :header | Attr[:width => :width, :body=>:title] >>
      <<:task_list | TaskHelper <
        %  tag_edit = (@current_task and @current_task.id == $_.id and @cmd == 'tag_edit')
        %  prj_sel = (@current_task and @current_task.id == $_.id and @cmd == 'prj_sel')
        <<tr :| Attr[:class=>:cycle_class] <
          <<th <
            <<?[ajax_task_done]<
              <<:done_check_ajax>>
            <<?![ajax_task_done]<
              <<:done_check>>

          << ?![prj_sel]<
            <<td :| Attr[:onclick=>:project_select_link] <
              <<:project_with_link>>

          << ?[prj_sel] <
            <<td <
              %= render :partial=>'inline_project_select', :locals=> { :task=>$_ }

          <<td <
              <<span :| Attr[:id=>:task_id] | Join[:nbsp] <
                <<span :| Attr[:id=>:handle_id] <
                  [+]
                <<:task_window_link>>
              <<:install_draggable>>

          << ?[show_tag and not tag_edit] <
            <<td :| Attr[:onclick=>:tag_edit_link] <
              << :taggings <
                <<a : | Attr[:href=>:tag_url, :body=>:tag_name] >>
                &#160;
              <img src="/images/s.gif" alt="spacer" height="1" />

          << ?[show_tag and tag_edit] <
            <<td <
              %= render :partial=>'inline_edit_tag', :locals=> { :task=>$_ }

      << ?[show_done_at] <
              <<td:done_at | StandardDateFormat>>
module TaskHelper
  include Amrita2View::Helper

  def task_id
    %[task_#{self.id}]
  end

  def handle_id
    %[task_handle_#{self.id}]
  end

  def checkbox_id
    %[chkbox_#{self.id}]
  end

  def tag_edit_id
    %[tag_edit_#{self.id}]
  end

  def cycle_class
    eval_in_view_without_escape do
      cycle('list-line-even', 'list-line-odd')
    end
  end

  def done_check_ajax
    task = self
    eval_in_view_without_escape do
      check_box_tag(task.checkbox_id, "1", task.done?) +
        javascript_tag(%[new CheckboxWatcher("#{task.checkbox_id}", "#{task.id}") ;])
    end
  end

  def done_check
    task = self
    eval_in_view_without_escape do
      check_box_tag task.checkbox_id, "1", task.done?, :onclick=>"location.href='#{url_for(:controller=>:tasks, :action=>:toggle_done, :id=>task.id)}'"
    end
  end


  def task_window_link
    task = self
    eval_in_view_without_escape do
      link_to_remote truncate(task.text, 50),
      {
        :url=> { :controller=>:main, :action=>:show_task_window, :id=>task.id },
        :update => 'task_work',
        :success=> %[ TaskWindow.show() ; ]
      },
      {
        :title=> task.text
      }
    end
  end

  def project_with_link
    project = self.project
    eval_in_view_without_escape do
      link_to truncate(project.name, 12),
        { :controller=>:project, :action=>:show, :id=>project.id },
        { :title => project.name }
    end
  end

  def taggings
    super.collect do |tagging|
      tagging.extend(TaggingHelper)
    end
  end

  def install_draggable
    task = self
    eval_in_view_without_escape do
      javascript_tag %[new Draggable('#{task.task_id}', {revert:true, ghosting:true, starteffect:null, handle:#{task.handle_id} });]
    end
  end

  def install_tag_complete
    eval_in_view_without_escape do
      %[<div id='task_tag_auto_complete' class='autocomplete' />] +
        auto_complete_field('task_tag', :url=>{ :action=>:complete_tag, :controller=>:main }, :tokens=>' ')
    end
  end

  def tag_edit_link
    task = self
    eval_in_view_without_escape do
      remote_function(:url=>{ :action=>:show_task, :id=>task.id, :cmd=>'tag_edit'})
    end
  end

  def project_select_link
    task = self
    eval_in_view_without_escape do
      remote_function(:url=>{ :action=>:show_task, :id=>task.id, :cmd=>'prj_sel'})
    end
  end
end