Notes about error handling and GWA changes.

<% @title = 'News' %>

<%= @title %>

This page lists the latest changes to and news about the Mushroom Observer website.

Sunday April 29, 2007

Substantially improved error handling.

Fixed problem with Google Web Accelerator.

Sunday April 22, 2007

Reorganized and simplified observation editing and creation.

Completed unit testing for existing pages.

Friday February 23, 2007

Adjusted the size of some of the notes widgets to fill more of the screen.

Monday February 19, 2007

Added note snippet and comment count to Show Image page for easier review.

Adjusted options available for the number of rows in list displays.

Fixed database migration scripts.

Internal data simplification (removed observations.what field).

Tuesday February 13, 2007

Added multiple upload option for Add Images.

Changed some of the links in the left hand panel based on user feedback.

Saturday February 10, 2007

Added image and location search within the site.

Thursday February 8, 2007

Added Google image search links to Observation and Name pages.

Wednesday February 7, 2007

Added checklists.  Items in the checklist are the results of the
                latest search or viewed species list.  Viewing large lists like
                'Latest Changes' or 'Name Index' will reset the checklist to all
                names.

Moved loading species lists from files to a separate page off of
                Edit Species List to avoid an interaction between the checklist
                and file loading.

Saturday January 27, 2007

Name edits now appear in the RSS feed.

Sunday January 21, 2007

Added How To Use page.

Changed 'New' links to 'Create'.

Fixed a bug with the search box.

Fixed a couple of bugs with the next/prev links.

Thursday January 11, 2007

Fixed a bug with creating new species.

Fixed many bugs with page titles, some of which were preventing pages from loading.

Tuesday January 9, 2007

Names are now database objects rather than just strings.  They have a
                rank, a text name an author and notes.

A show_name page shows this information as well as a list of all
        observations that use that Name.  The show_pages can be accessed from
        each show_observation page as well as the name_index page that is
        available in the left-side panel.

Names can be edited on the edit_name pages that are accessible from
        the show_name pages.  Anyone is allowed to edit any name, but
        following the Wikipedia model,
        a record is kept of every version.  The previous versions are stored as
        'past names'.  A show_past_name page shows the name information for a
        previous version of a name and is accessible from each show_name page.

Names are associated with observations through the 'what' field of the
        observation.  When the 'what' field is changed, the names are searched
        for a match.  The 'what' field can either be the text_name or the
        text_name and the author for a name.  No match is found for a 'what'
        value, then the user is given the option to create the new name.  If a
        'what' value matches more than one name (due to different authors
        publishing the same name), then the user is given a choice between the
        options.  The options list how many observations use each version of
        the name.  If you add an author to a 'what' field for a name that does
        not have an author already, it will ask you if you want to create the
        new name, but it will actually update the existing name.

Names given in species lists are treated in the exact same manner,
        except that all the new names and all of the multiple matches are
        dealt with on the same page.  There is also an option on the
        new_species_list and edit_species_list pages to 'Just Create New
        Names'.  This adds the names without updating the species list or
        creating the corresponding observations.

The search box is now available on every page.

Removed the Observation Index in favor of the Name Index.

Fixed some of the list ordering to make it more intuitive.

A filter was added to the account creation process that should reduce the
        number of bot created users.

Fixed a bug with bouncing between observations and images and using the
        next/prev links.

Monday December 18, 2006

Added prev/next links that follow the RSS feed.

Improved prev/next functionality throughout the site.

RSS feed descriptions now have appropriate line breaks.

Monday December 4, 2006

Species lists can now be uploaded from files.

Separated note for species list from note that applies to member observations.

Fixed use of multiple tabs by switching from session data to hidden fields.

mushroomobserver.org/# == mushroomobserver.org/observer/show_observation/#

Monday October 26, 2006

Switched Observations->By Name to include thumbnails and follow layout.

Maintained old By Name behavior as Observations->Index.

Added simple search box to Activity Log (Latest Changes) and Observation list pages.

Monday October 23, 2006

Changed default page to the RSS feed.

Changed page layout for observation and image list pages.

Added layout controls to user preferences.  Set to 10 rows x 1 column
			and turn off 'Put text below images' to get old layout.

Changed thumbnail image size from 100px to 160px with lower quality (jpeg 50 vs. 75).

Provided Prev/Next buttons for images.

Added link to ask the webmaster a question about the site.

Split up 'Manage Images' into 'Add Image', 'Reuse Image' and 'Remove Images' and made
			them more visible.

'Reuse Image' allows you to look at the images.

Added links for viewing the log for observations and species lists.

Made database lookup for all observations much more efficient.

Rearranged left-hand panel.

Images no longer have titles.  They are derived from the observation(s) they are
			connected to.

Removed Edit and Destroy links from view pages.

Add mini-icon for webpages.

Sunday September 9, 2006

Links to email the creator of observations or images with questions or commerical inquiries.  The creator receives an email with the address of the user who wants to contact them.  It is up to the creator whether they want to respond.

User preferences added to disable the above email feature and to stop receiving emails like this letting you know about new features.

RSS feed has been overhauled to reduce the number of entries and make them more relevant.

Copyright holder now has an option to be something other than a registered user.  The user who uploads the image is the default, but it can now be changed on a per image basis.

Monday August 21, 2006

	Added RSS feed for all interesting events that happen on the site.

	Added 'Create Account' link on login page to make it more obvious.

	Tweaked page titles to make the site easier to index.

Sunday August 13, 2006

	Added this news page.

	List pages now have a better interface for paging than just next/previous,
	and its at the top and bottom of each page.

Saturday August 12, 2006

	Added email verification system to user signup.

<% @title = 'News' %>

<%= @title %>

This page lists the latest changes to and news about the Mushroom Observer website.

Sunday April 22, 2007

Reorganized and simplified observation editing and creation.

Completed unit testing for existing pages.

Friday February 23, 2007

Adjusted the size of some of the notes widgets to fill more of the screen.

Monday February 19, 2007

Added note snippet and comment count to Show Image page for easier review.

Adjusted options available for the number of rows in list displays.

Fixed database migration scripts.

Internal data simplification (removed observations.what field).

Tuesday February 13, 2007

Added multiple upload option for Add Images.

Changed some of the links in the left hand panel based on user feedback.

Saturday February 10, 2007

Added image and location search within the site.

Thursday February 8, 2007

Added Google image search links to Observation and Name pages.

Wednesday February 7, 2007

Added checklists.  Items in the checklist are the results of the
                latest search or viewed species list.  Viewing large lists like
                'Latest Changes' or 'Name Index' will reset the checklist to all
                names.

Moved loading species lists from files to a separate page off of
                Edit Species List to avoid an interaction between the checklist
                and file loading.

Saturday January 27, 2007

Name edits now appear in the RSS feed.

Sunday January 21, 2007

Added How To Use page.

Changed 'New' links to 'Create'.

Fixed a bug with the search box.

Fixed a couple of bugs with the next/prev links.

Thursday January 11, 2007

Fixed a bug with creating new species.

Fixed many bugs with page titles, some of which were preventing pages from loading.

Tuesday January 9, 2007

Names are now database objects rather than just strings.  They have a
                rank, a text name an author and notes.

A show_name page shows this information as well as a list of all
        observations that use that Name.  The show_pages can be accessed from
        each show_observation page as well as the name_index page that is
        available in the left-side panel.

Names can be edited on the edit_name pages that are accessible from
        the show_name pages.  Anyone is allowed to edit any name, but
        following the Wikipedia model,
        a record is kept of every version.  The previous versions are stored as
        'past names'.  A show_past_name page shows the name information for a
        previous version of a name and is accessible from each show_name page.

Names are associated with observations through the 'what' field of the
        observation.  When the 'what' field is changed, the names are searched
        for a match.  The 'what' field can either be the text_name or the
        text_name and the author for a name.  No match is found for a 'what'
        value, then the user is given the option to create the new name.  If a
        'what' value matches more than one name (due to different authors
        publishing the same name), then the user is given a choice between the
        options.  The options list how many observations use each version of
        the name.  If you add an author to a 'what' field for a name that does
        not have an author already, it will ask you if you want to create the
        new name, but it will actually update the existing name.

Names given in species lists are treated in the exact same manner,
        except that all the new names and all of the multiple matches are
        dealt with on the same page.  There is also an option on the
        new_species_list and edit_species_list pages to 'Just Create New
        Names'.  This adds the names without updating the species list or
        creating the corresponding observations.

The search box is now available on every page.

Removed the Observation Index in favor of the Name Index.

Fixed some of the list ordering to make it more intuitive.

A filter was added to the account creation process that should reduce the
        number of bot created users.

Fixed a bug with bouncing between observations and images and using the
        next/prev links.

Monday December 18, 2006

Added prev/next links that follow the RSS feed.

Improved prev/next functionality throughout the site.

RSS feed descriptions now have appropriate line breaks.

Monday December 4, 2006

Species lists can now be uploaded from files.

Separated note for species list from note that applies to member observations.

Fixed use of multiple tabs by switching from session data to hidden fields.

mushroomobserver.org/# == mushroomobserver.org/observer/show_observation/#

Monday October 26, 2006

Switched Observations->By Name to include thumbnails and follow layout.

Maintained old By Name behavior as Observations->Index.

Added simple search box to Activity Log (Latest Changes) and Observation list pages.

Monday October 23, 2006

Changed default page to the RSS feed.

Changed page layout for observation and image list pages.

Added layout controls to user preferences.  Set to 10 rows x 1 column
			and turn off 'Put text below images' to get old layout.

Changed thumbnail image size from 100px to 160px with lower quality (jpeg 50 vs. 75).

Provided Prev/Next buttons for images.

Added link to ask the webmaster a question about the site.

Split up 'Manage Images' into 'Add Image', 'Reuse Image' and 'Remove Images' and made
			them more visible.

'Reuse Image' allows you to look at the images.

Added links for viewing the log for observations and species lists.

Made database lookup for all observations much more efficient.

Rearranged left-hand panel.

Images no longer have titles.  They are derived from the observation(s) they are
			connected to.

Removed Edit and Destroy links from view pages.

Add mini-icon for webpages.

Sunday September 9, 2006

Links to email the creator of observations or images with questions or commerical inquiries.  The creator receives an email with the address of the user who wants to contact them.  It is up to the creator whether they want to respond.

User preferences added to disable the above email feature and to stop receiving emails like this letting you know about new features.

RSS feed has been overhauled to reduce the number of entries and make them more relevant.

Copyright holder now has an option to be something other than a registered user.  The user who uploads the image is the default, but it can now be changed on a per image basis.

Monday August 21, 2006

	Added RSS feed for all interesting events that happen on the site.

	Added 'Create Account' link on login page to make it more obvious.

	Tweaked page titles to make the site easier to index.

Sunday August 13, 2006

	Added this news page.

	List pages now have a better interface for paging than just next/previous,
	and its at the top and bottom of each page.

Saturday August 12, 2006

	Added email verification system to user signup.


Fixed wording error in welcome page

Fixed wording error in welcome page

What is efl?

The Edmonton Free Library is a book, music, and video sharing community operating in the Edmonton capital region.

efl operates on library-like principles where each person can lend books upon request to other participants. This kind of bottom-up and de-centralized approach to sharing culture can help you find and share caches of interesting material with other cool people.

How does it work?

Create an account!, then list the books and videos that you own.
 You will quickly be able to borrow from the multitude of books and other material in other
collections.  You can search for specific authors or titles, browse individual
collections, find nearby users, or find people who like books in common with yours.
Read the reviews and then write your own when you finish the book!

When the owner of a book or video you're interested in has time for you to pick it up or meet you,
then you can borrow books and video (with a due date set by the owner).

Returning books late will get you negative feedback, while returning books promptly
will get you positive feedback.  You are never under any obligation to lend an item if you don't feel comfortable doing so.

How do you manage trust?

While this is a community site based on good will, we will have an ebay-style feedback system for managing trust.  Lenders have the opportunity to leave positive or negative feedback for borrowers when an item is returned.  These positive or negative points contribute to an overall "score" which lenders can use to gauge the trustworthiness or responsibility of a borrower.  Lenders can also leave comments along with the points to be more specific.

What is efl?

The Edmonton Free Library is a book, music, and video sharing community operating in the Edmonton capital region.

efl operates on library-like principles where each person can lend books upon request to other participants. This kind of bottom-up and de-centralized approach to sharing culture should could help you find and share caches of interesting material with other cool people.

How does it work?

Create an account!, then list the books and videos that you own.
 You will quickly be able to borrow from the multitude of books and other material in other
collections.  You can search for specific authors or titles, browse individual
collections, find nearby users, or find people who like books in common with yours.
Read the reviews and then write your own when you finish the book!

When the owner of a book or video you're interested in has time for you to pick it up or meet you,
then you can borrow books and video (with a due date set by the owner).

Returning books late will get you negative feedback, while returning books promptly
will get you positive feedback.  You are never under any obligation to lend an item if you don't feel comfortable doing so.

How do you manage trust?

While this is a community site based on good will, we will have an ebay-style feedback system for managing trust.  Lenders have the opportunity to leave positive or negative feedback for borrowers when an item is returned.  These positive or negative points contribute to an overall "score" which lenders can use to gauge the trustworthiness or responsibility of a borrower.  Lenders can also leave comments along with the points to be more specific.


fix string escaping error in sharing form

<%
   object ||= nil
   set_parameters_for_sharing_form object
   disable_advanced_view ||= nil
   show_advanced_permissions = !@resource.respond_to?(:has_advanced_permissions?) || @resource.has_advanced_permissions?
   default_projects_access_type = @resource.is_asset? ? Policy::ACCESSIBLE : Policy::EDITING
   default_consortium_access_type = Policy::VISIBLE
   can_publish = @resource.respond_to?(:can_publish?) ? @resource.can_publish? : true
%>
<%# initialization: required to keep javascript independent of the access type codes, to allow the use the constants instead -%>
<%= render :partial=>"assets/sharing_constants" %>

<%# this hidden input will submit all permission data with the form -%>
<%= hidden_field_tag "sharing[permissions][contributor_types]", "" -%>
<%= hidden_field_tag "sharing[permissions][values]", "" -%>

<%="
" if !@resource.errors.empty? and !@policy.valid? %>

    <%= help_icon("Here you can specify who can see#{', download' if @resource.is_downloadable?} and edit this #{@resource_type}.") -%>
    Sharing

        Here you can specify who can view the summary of<% if @resource.is_downloadable? %>, get access to the content of,<% end %> and edit the <%= @resource_type -%>.
        <%= link_to_function "More info " + expand_image, visual_effect(:toggle_blind, "more_sharing_info", :duration => 0.3) -%>

          You may:

Keep the <%= @resource_type -%> private, and only visible to yourself.

          <%
             through_resource = ''
             if @resource.kind_of?(Assay)
               through_resource = '(through projects associated with selected study)'
             elsif @resource.kind_of?(Study)
               through_resource = '(through projects associated with selected investigation)'
             end
          %>

Share within members of projects associated with this <%= @resource_type -%> <%= through_resource%> and with all other users that are a member of a <%= Seek::Config.project_name %> project.

Share with the all visitors (including anonymous visitors with no login)

You can share with the all visitors right away if you are the gatekeeper or if the projects associated with this <%= @resource_type -%> have no gatekeeper

Or you can request the gatekeepers for their approval to share with all visitors

          <% if !disable_advanced_view%>

Define more fine-grained sharing in the Advanced sharing: you can share within your Project/Institution only,
 with specific individuals, or set up custom favourite groups for people you regularly need to share with.

          <% end %>

<label for="sharing_scope_<%= Policy::PRIVATE -%>">
            <input type="hidden" id='access_type_select_<%= Policy::PRIVATE -%>' name="sharing[access_type_<%= Policy::PRIVATE -%>]" value="<%= Policy::NO_ACCESS -%>">
            <input <%= 'checked="checked"' if @sharing_mode == Policy::PRIVATE %> id="sharing_scope_<%= Policy::PRIVATE -%>" name="sharing[sharing_scope]"
                                                                                value="<%= Policy::PRIVATE -%>" type="radio" />
            - Keep this <%= @resource_type -%> private (only visible to you)

          <%= additional_advanced_permissions_included @resource, Policy::PRIVATE -%>

Or share it with..

            <input type="radio" <%= 'checked="checked"' if @sharing_mode == Policy::ALL_SYSMO_USERS -%> id="sharing_scope_<%= Policy::ALL_SYSMO_USERS -%>" name="sharing[sharing_scope]" value="<%= Policy::ALL_SYSMO_USERS -%>" />
            - Members of projects associated with this <%= @resource_type -%>:

             <select name="sharing[your_proj_access_type]" id="sharing_your_proj_access_type">
                 <%= policy_selection_options([Policy::VISIBLE,Policy::ACCESSIBLE,Policy::EDITING,Policy::MANAGING], @resource, your_project_access_type(@policy, @resource) || default_projects_access_type) -%>
             </select>

            ... and all other project members:
             <%= render :partial => "assets/sharing_form_access_type_dropdown", :locals => { :access_type_selector_for_scope => Policy::ALL_SYSMO_USERS,
               :sharing_scope => Policy::ALL_SYSMO_USERS, :access_type => (@resource.respond_to?(:policy) && @resource.policy.try(:sharing_scope)==Policy::ALL_SYSMO_USERS ? @access_mode : default_consortium_access_type), :access_type_options=>[Policy::NO_ACCESS,Policy::VISIBLE,Policy::ACCESSIBLE,Policy::EDITING] } -%>
             <%= additional_advanced_permissions_included @resource, Policy::ALL_SYSMO_USERS -%>

          <label for="sharing_scope_<%= Policy::EVERYONE -%>">
            <input type="radio" <%= 'checked="checked"' if @sharing_mode == Policy::EVERYONE -%> id="sharing_scope_<%= Policy::EVERYONE -%>" name="sharing[sharing_scope]"
                   value="<%= Policy::EVERYONE -%>"/>
            - All visitors (including anonymous visitors with no login):

           <%= render :partial => "assets/sharing_form_access_type_dropdown", :locals => { :access_type_selector_for_scope => Policy::EVERYONE,
            :sharing_scope => @sharing_mode, :access_type => @access_mode } -%>
           <%= additional_advanced_permissions_included @resource, Policy::EVERYONE -%>

    <% if @resource.new_record? && @resource.errors.empty? -%>

    <% end -%>

    <% if !disable_advanced_view %>
      <%= link_to_function "Advanced permissions " + expand_image, :class => 'advanced_sharing_link', :style => "display:" + (show_advanced_permissions ? 'none;' : 'block;'), :id =>'advanced_sharing_expand_image' do |page|
          page.visual_effect :toggle_blind, "advanced sharing", :duration => 0.5
          page["advanced_sharing_expand_image"].toggle
          page["advanced_sharing_collapse_image"].toggle
      end
      -%>
      <%= link_to_function "Advanced permissions " + collapse_image, :class => 'advanced_sharing_link', :style => "display:" + (show_advanced_permissions ? 'block;' : 'none;'), :id =>'advanced_sharing_collapse_image' do |page|
          page.visual_effect :toggle_blind, "advanced sharing", :duration => 0.5
          page["advanced_sharing_expand_image"].toggle
          page["advanced_sharing_collapse_image"].toggle
      end
      -%>

      <div id="advanced sharing" class='sharing_box_form' style="display:<%= show_advanced_permissions ? 'block;' : 'none;' -%>">

Additional fine-grained sharing permissions

              So far you have selected to share this <%= @resource_type -%> with:

              Loading...

              Build up the list of people and groups to share with.
              Select from the options below and click "Add" to apply
              your choices and add collaborators to your current selection:

                <%= image_tag icon_filename_for_key("spinner"), :id => "f_group_deleting_spinner", :alt=>"loading...", :title=>"loading...", :style => "display: none; vertical-align: middle; float: right;" -%>
                <%= help_icon("Here you can choose your favourite groups to share this #{@resource_type} with.") -%>
                Favourite Groups

                  <% favourite_groups = FavouriteGroup.get_all_without_blacklists_and_whitelists(current_user.id) -%>
                  <% f_group_select_options = (favourite_groups.blank? ? "<option value=\"\">You don't have any favourite groups</option>" : options_for_select(favourite_groups)) -%>

                  <%= select_tag "favourite_group_select", f_group_select_options, :style => "width: 82%; vertical-align: middle; margin-right: 0.4em;", :disabled => (favourite_groups.blank?) -%>

                  <%= link_to "Add", "", :id => "add_f_group_link", :style => "font-weight: bold; vertical-align: middle;", :disabled => (favourite_groups.blank?),
                              :onclick => "javascript: if($('favourite_group_select').disabled) return(false); addContributor('FavouriteGroup', $('favourite_group_select').options[$('favourite_group_select').selectedIndex].text, parseInt($('favourite_group_select').options[$('favourite_group_select').selectedIndex].value), #{Policy::DETERMINED_BY_GROUP}); return(false);" -%>

                  <li id="edit_f_group_li" style="display: <%= favourite_groups.blank? ? "none" : "block" -%>; list-style-type: disc; padding: 0;"><%= favourite_group_popup_link_action_edit(@resource.class.name) -%>

                  <li id="delete_f_group_li" style="display: <%= favourite_groups.blank? ? "none" : "block" -%>; list-style-type: disc; padding: 0;">
                    <%= link_to "Delete selected favourite group", delete_favourite_group_path(0), :onclick => "deleteSelectedFavouriteGroup(); return(false);" -%>

<%= favourite_group_popup_link_action_new(@resource.class.name) -%>

                <%= help_icon("Here you can choose projects, institutions and workgroups to share this #{@resource_type} with.") -%>
                Projects and Institutions

                  <% right_arrow_image = icon_filename_for_key("arrow_right") -%>

                  Step 1
                  <%= image_tag right_arrow_image, :style => "vertical-align: middle; padding: 0 0.8em;" -%>

                  Step 2
                  <%= image_tag right_arrow_image, :style => "vertical-align: middle; padding: 0 0.8em;" -%>

                  Step 3

                    <input type="hidden" id="proj_select_step_index" value="1">

                      <%= image_tag icon_filename_for_key("spinner"), :id => "institutions_loading_spinner", :alt=>"loading...", :title=>"loading...", :style => "display: none; vertical-align: middle; float: right;" -%>
                      Step 1: Select a project
                      <%= select("proj_project", "select",
                                 Project.find(:all).collect { |p| [p.name, p.id] },
                                 {:include_blank => 'All Projects @ Institution (from Step 2)'}, {:style => "width: 100%; vertical-align: middle; margin: 0.3em 0;"}) -%>

                      Step 2: Select scope of the project
                      <%= select_tag("proj_institution_select", nil, {:style => "width: 100%; vertical-align: middle; margin: 0.3em 0;"}) -%>

                      Step 3: Choose access rights, review and
                      submit

                      <select name="proj_access_type_select" id="proj_access_type_select" onchange="javascript: replaceReviewWorkGroupURL();" style="width: 100%; vertical-align: middle; margin: 0.3em 0;">
                        <%= policy_selection_options [Policy::NO_ACCESS, Policy::VISIBLE, Policy::ACCESSIBLE, Policy::EDITING, Policy::MANAGING], @resource -%>
                      </select>

                        <%= link_to "< Previous step", "", :onclick => "javascript: projectInstitutionStepAction(-1); return(false);", :style => "font-weight: bold;" -%>

                        <%= link_to "Next step >", "", :onclick => "javascript: projectInstitutionStepAction(1); return(false);", :style => "font-weight: bold;" -%>

                          <%= link_to "Add immediately", "", :onclick => "javascript: addProjectInstitution(); return(false);", :style => "font-weight: bold; padding: 0;" -%>

<%= workgroup_member_review_popup_link(@resource.class.name) -%>

                <%= help_icon("Here you can specify individual people to share this #{@resource_type} with.") -%>
                Individual People

                    Please type names of people to share this <%= @resource_type -%> with into the box below -
                    suggestions will be displayed as you type.
                    Select access rights from drop-down menu; these will be applied to all chosen people.
                    Clicking "Add" will add selected people to the list.

                          ^_^<input type="text" id="ip_hidden_input" tabindex="-1">

                            <input type="text" size="1" tabindex="" id="ip_autocomplete_input"/>

Type the name of a friend, friend list, or email address

                        <select name="individual_people_access_type_select" id="individual_people_access_type_select" style="width: 344px; vertical-align: middle; margin-top: 0.3em;">
                          <%= policy_selection_options nil, @resource -%>
                        </select>

                        <%= link_to "Add", "", :onclick => "javascript: addIndividualPeople(); return(false);" -%>

  <% end %>

<%="
" if !@resource.errors.empty? and !@policy.valid? %>


Point people at the wiki when GPX imports fail.

Hi,

It looks like your GPX file

  <%= @trace_name %>

failed to import. Here's the error:

  <%= @error %>

More information about GPX import failures and how to avoid
them can be found at:

  http://wiki.openstreetmap.org/index.php/GPX_Import_Failures


[ClockingIT @ Don't escape tags list for completed tasks.]

<% cache( :controller => "tasks", :action => "task_row", :action_suffix => "#{task.id}_#{session[:user].id}_#{session[:filter_user].to_i}_#{session[:filter_milestone]}_#{tz.now.strftime('%d%m%y')}") do %>

<li id="task_<%=task.id%>"

<%
 priority = ""
 priority = " task_raised_pri" if (task.priority + task.severity_id)/2.0 >= 0.1 && !task.done?
 priority = " task_high_pri" if (task.priority + task.severity_id)/2.0 >= 0.51 && !task.done?
 priority = " task_crit_pri" if (task.priority + task.severity_id)/2.0 >= 1.5 && !task.done?
 priority = " task_low_pri" if (task.priority + task.severity_id)/2 < -0.51 && !task.done?
 priority = " task_lowest_pri" if (task.priority + task.severity_id)/2 < -1.5 && !task.done?

 can_complete = { :disabled => "disabled" } unless session[:user].can?(task.project, 'close')
 can_complete ||= {}

 can_work = { :disabled => "disabled" } unless session[:user].can?(task.project, 'work')
 can_work ||= {}

 priority << " #{task.project.to_css_name}"

%>

<% if @session[:sheet] && @session[:sheet].task.id == task.id %>
class="task_active<%=priority%>"
<% elsif task.done? %>
class="task_done<%=priority%>"
<% else %>
class="task<%=priority%>"
<% end %>
  onMouseOver="javascript:Hover('task', '<%=task.id%>')" onMouseOut="javascript:ClearHover()">

<% @task = task %>

  <% unless task.done?
    %>
    <%= check_box("task", "done", { "title" => _("Close %s", task.name), "onclick" => remote_function(:url => { :controller => 'tasks', :action => 'ajax_check', :id => task },
                                                                :loading => "Element.show('loading');",
                                                                :complete => "Element.hide('loading');" ), :class => "button tooltip", :id => "button_#{task.id}" }.merge(can_complete) ) -%>
    <% if @session[:user].option_tracktime == 1 && can_work.size == 0 -%>
      <% if @session[:sheet] && @session[:sheet].task.id == task.id -%>
        <%= link_to(image_tag("time_add.png", :border => 0, :class => "tooltip work_icon", :title => _("Stop working on %s.", task.name)), {:controller => 'tasks', :action => 'stop_work'})  -%>
      <% else -%>
        <%= link_to_remote( image_tag("time.png", :border => 0, :class => "tooltip work_icon", :title => _("Start working on %s. Click again when done.", task.name)),
                        :url => {:controller => 'tasks', :action => 'start_work_ajax', :id => task },
                        :loading => "Element.show('loading');",
                        :complete => "Element.hide('loading');") -%>
      <% end -%>
   <% else -%>

   <% end -%>
   <%= link_to_task(task) -%>

     <%= "(#{worked_nice(task.worked_minutes)} / #{worked_nice( task.duration )})" if (@session[:user].option_tracktime == 1 && task.duration > 0) %>
     <%= "[#{task.milestone.name}]" unless task.milestone.nil? -%>

   <% name = _("No one")
      name = task.users.collect{|u| u.name}.join(', ') unless task.users.empty?
   %>

   <% if session[:user].option_tracktime == 1 %>

   <% else %>

   <% end %>
   <%= task.full_name %>
   <%= "[#{name}]" %>
   <%= due_in_words(task) if (task.due_at != nil || task.milestone_id.to_i > 0)%>

  <% else %>
  <%#
    # Task is complete
    #%>
    <%= check_box("task", "done", {"title" => _("Revert %s to not completed status.", task.name), "onclick" => remote_function(:url => { :controller => 'tasks', :action => 'ajax_uncheck', :id => task },
                                                                :loading => "Element.show('loading');",
                                                                :complete => "Element.hide('loading');" ), :class => "button tooltip", :checked => "checked", :id => "button_#{task.id}" }.merge(can_complete) ) -%>
    <% if @session[:user].option_tracktime == 1 && can_work.size == 0 -%>
      <% if @session[:sheet] && @session[:sheet].task.id == task.id -%>
        <%= link_to(image_tag("time_add.png", :border => 0, :class => "tooltip work_icon", :title => _("Stop working on %s.", task.name)), {:controller => 'tasks', :action => 'stop_work'})  -%>
      <% else -%>
        <%= link_to_remote( image_tag("time.png", :border => 0, :class => "tooltip work_icon", :title => _("Start working on %s. Click again when done.", task.name)),
                        :url => {:controller => 'tasks', :action => 'start_work_ajax', :id => task },
                        :loading => "Element.show('loading');",
                        :complete => "Element.hide('loading');") -%>
     <% end -%>
   <% else -%>
     <% end -%>
     <%= link_to_task(task) -%>
     <% if @session[:user].option_tracktime == 1%>(<%= worked_nice(task.worked_minutes) %> / <%= worked_nice( task.duration ) %>)<% end %> [<%=tz.utc_to_local(task.completed_at).strftime(session[:user].date_format) %>]
     <% if session[:user].option_tracktime == 1 %>

<%= task.full_name %>

     <% else %>

<%= task.full_name %>

     <% end %>

  <% end %>

  <%#
    # Always printed
    #%>

    <span id="edit_task_<%=task.id%>" style="display: none;">
      <% if @session[:sheet] && @session[:sheet].task.id == task.id -%>
        <%= link_to_remote image_tag("time_delete.png", :border => 0, :title => _("Cancel working on %s.", task.name), :class => "tooltip"),
          :url => { :controller => 'tasks', :action => 'cancel_work_ajax', :id => task },
          :loading => "Element.show('loading');",
          :complete => "Element.hide('loading');" -%>
      <% else -%>
        <% if task.done? -%>
          <% if task.hidden == 0 -%>
            <%= link_to_remote image_tag("folder_add.png", :border => 0, :title => _("Move %s to the Archive.", task.name), :class => "tooltip"),
                  :url => { :controller => 'tasks', :action => 'ajax_hide', :id => task },
                  :loading => "Element.show('loading');",
                  :complete => "Element.hide('loading');",
                  :success => visual_effect(:fade, "task_#{task.id}", :duration => 0.5) -%>
          <% else -%>
            <%= link_to_remote image_tag("folder_go.png", :border => 0, :title => _("Restore %s from the Archive.", task.name), :class => "tooltip"),
                  :url => { :controller => 'tasks', :action => 'ajax_restore', :id => task },
                  :loading => "Element.show('loading');",
                  :complete => "Element.hide('loading');",
                  :success => visual_effect(:fade, "task_#{task.id}", :duration => 0.5) -%>
          <% end -%>
        <% end -%>
      <% end -%>

<% end %>

<% cache( :controller => "tasks", :action => "task_row", :action_suffix => "#{task.id}_#{session[:user].id}_#{session[:filter_user].to_i}_#{session[:filter_milestone]}_#{tz.now.strftime('%d%m%y')}") do %>

<li id="task_<%=task.id%>"

<%
 priority = ""
 priority = " task_raised_pri" if (task.priority + task.severity_id)/2.0 >= 0.1 && !task.done?
 priority = " task_high_pri" if (task.priority + task.severity_id)/2.0 >= 0.51 && !task.done?
 priority = " task_crit_pri" if (task.priority + task.severity_id)/2.0 >= 1.5 && !task.done?
 priority = " task_low_pri" if (task.priority + task.severity_id)/2 < -0.51 && !task.done?
 priority = " task_lowest_pri" if (task.priority + task.severity_id)/2 < -1.5 && !task.done?

 can_complete = { :disabled => "disabled" } unless session[:user].can?(task.project, 'close')
 can_complete ||= {}

 can_work = { :disabled => "disabled" } unless session[:user].can?(task.project, 'work')
 can_work ||= {}

 priority << " #{task.project.to_css_name}"

%>

<% if @session[:sheet] && @session[:sheet].task.id == task.id %>
class="task_active<%=priority%>"
<% elsif task.done? %>
class="task_done<%=priority%>"
<% else %>
class="task<%=priority%>"
<% end %>
  onMouseOver="javascript:Hover('task', '<%=task.id%>')" onMouseOut="javascript:ClearHover()">

<% @task = task %>

  <% unless task.done?
    %>
    <%= check_box("task", "done", { "title" => _("Close %s", task.name), "onclick" => remote_function(:url => { :controller => 'tasks', :action => 'ajax_check', :id => task },
                                                                :loading => "Element.show('loading');",
                                                                :complete => "Element.hide('loading');" ), :class => "button tooltip", :id => "button_#{task.id}" }.merge(can_complete) ) -%>
    <% if @session[:user].option_tracktime == 1 && can_work.size == 0 -%>
      <% if @session[:sheet] && @session[:sheet].task.id == task.id -%>
        <%= link_to(image_tag("time_add.png", :border => 0, :class => "tooltip work_icon", :title => _("Stop working on %s.", task.name)), {:controller => 'tasks', :action => 'stop_work'})  -%>
      <% else -%>
        <%= link_to_remote( image_tag("time.png", :border => 0, :class => "tooltip work_icon", :title => _("Start working on %s. Click again when done.", task.name)),
                        :url => {:controller => 'tasks', :action => 'start_work_ajax', :id => task },
                        :loading => "Element.show('loading');",
                        :complete => "Element.hide('loading');") -%>
      <% end -%>
   <% else -%>

   <% end -%>
   <%= link_to_task(task) -%>

     <%= "(#{worked_nice(task.worked_minutes)} / #{worked_nice( task.duration )})" if (@session[:user].option_tracktime == 1 && task.duration > 0) %>
     <%= "[#{task.milestone.name}]" unless task.milestone.nil? -%>

   <% name = _("No one")
      name = task.users.collect{|u| u.name}.join(', ') unless task.users.empty?
   %>

   <% if session[:user].option_tracktime == 1 %>

   <% else %>

   <% end %>
   <%= task.full_name %>
   <%= "[#{name}]" %>
   <%= due_in_words(task) if (task.due_at != nil || task.milestone_id.to_i > 0)%>

  <% else %>
  <%#
    # Task is complete
    #%>
    <%= check_box("task", "done", {"title" => _("Revert %s to not completed status.", task.name), "onclick" => remote_function(:url => { :controller => 'tasks', :action => 'ajax_uncheck', :id => task },
                                                                :loading => "Element.show('loading');",
                                                                :complete => "Element.hide('loading');" ), :class => "button tooltip", :checked => "checked", :id => "button_#{task.id}" }.merge(can_complete) ) -%>
    <% if @session[:user].option_tracktime == 1 && can_work.size == 0 -%>
      <% if @session[:sheet] && @session[:sheet].task.id == task.id -%>
        <%= link_to(image_tag("time_add.png", :border => 0, :class => "tooltip work_icon", :title => _("Stop working on %s.", task.name)), {:controller => 'tasks', :action => 'stop_work'})  -%>
      <% else -%>
        <%= link_to_remote( image_tag("time.png", :border => 0, :class => "tooltip work_icon", :title => _("Start working on %s. Click again when done.", task.name)),
                        :url => {:controller => 'tasks', :action => 'start_work_ajax', :id => task },
                        :loading => "Element.show('loading');",
                        :complete => "Element.hide('loading');") -%>
     <% end -%>
   <% else -%>
     <% end -%>
     <%= link_to_task(task) -%>
     <% if @session[:user].option_tracktime == 1%>(<%= worked_nice(task.worked_minutes) %> / <%= worked_nice( task.duration ) %>)<% end %> [<%=tz.utc_to_local(task.completed_at).strftime(session[:user].date_format) %>]
     <% if session[:user].option_tracktime == 1 %>

<%= h(task.full_name) %>

     <% else %>

<%= h(task.full_name) %>

     <% end %>

  <% end %>

  <%#
    # Always printed
    #%>

    <span id="edit_task_<%=task.id%>" style="display: none;">
      <% if @session[:sheet] && @session[:sheet].task.id == task.id -%>
        <%= link_to_remote image_tag("time_delete.png", :border => 0, :title => _("Cancel working on %s.", task.name), :class => "tooltip"),
          :url => { :controller => 'tasks', :action => 'cancel_work_ajax', :id => task },
          :loading => "Element.show('loading');",
          :complete => "Element.hide('loading');" -%>
      <% else -%>
        <% if task.done? -%>
          <% if task.hidden == 0 -%>
            <%= link_to_remote image_tag("folder_add.png", :border => 0, :title => _("Move %s to the Archive.", task.name), :class => "tooltip"),
                  :url => { :controller => 'tasks', :action => 'ajax_hide', :id => task },
                  :loading => "Element.show('loading');",
                  :complete => "Element.hide('loading');",
                  :success => visual_effect(:fade, "task_#{task.id}", :duration => 0.5) -%>
          <% else -%>
            <%= link_to_remote image_tag("folder_go.png", :border => 0, :title => _("Restore %s from the Archive.", task.name), :class => "tooltip"),
                  :url => { :controller => 'tasks', :action => 'ajax_restore', :id => task },
                  :loading => "Element.show('loading');",
                  :complete => "Element.hide('loading');",
                  :success => visual_effect(:fade, "task_#{task.id}", :duration => 0.5) -%>
          <% end -%>
        <% end -%>
      <% end -%>

<% end %>


Fix crash by using method name

Fix crash by using method name

<% extra_content = [] %>
<% extra_content_list = [] %>

<%= _('Products/Services') %>

<% if @categories %>
  <%= breadcrumb(@category) if params[:level] %>

      <%= content_tag('li', link_to(_('Homepage'), profile.url), :class => 'catalog-categories-link') %>
      <%= content_tag('li', link_to(_('Catalog start'), profile.catalog_url), :class => 'catalog-categories-link') %>
      <% if @categories.present? %>
        <% @categories.each do |category| %>
          <%= category_link(category) %>
          <%= category_sub_links(category) %>
        <% end %>
      <% elsif @category.present? %>
        <%= content_tag('li', _('There are no sub-categories for %s') % @category.name, :id => 'catalog-categories-notice') %>
      <% else %>
        <%= content_tag('li', _('There are no categories available.'), :id => 'catalog-categories-notice') %>
      <% end %>

<% end %>

<ul id="product-list" class="<%="l-sidebar-left-content" if @categories %>">
  <% @products.each do |product| %>
    <% extra_content = @plugins.dispatch(:catalog_item_extras, product).collect { |content| instance_eval(&content) } %>
    <% extra_content_list = @plugins.dispatch(:catalog_list_item_extras, product).collect { |content| instance_eval(&content) } %>

    <% status = [] %>
    <% status << 'not-available' if !product.available %>
    <% status << 'highlighted' if product.highlighted %>

    <li id="product-<%= product.id %>" class="product <%= status.join(' ') %>">

          <% if product.highlighted? %>
            <%= link_to image_tag(themed_path('/images/star.png'), :class => 'star', :alt => _('Highlighted product')), product_path(product) %>
          <% end %>
          <% if product.image %>

              <%= link_to_product product, :class => 'product-big', :style => "background-image: url(#{product.default_image(:big)})" %>
              <%= link_to content_tag(:span, _('Zoom in')), product.default_image(:big).gsub('_big',''), :class => 'zoomify-image' %>

          <% else %>

<%= _('No image') %>

          <% end %>

<%= extra_content.join("\n") %>

<%= link_to_product product %>

          <% unless product.discount.blank? or product.discount == 0 %>

              <%= _('from ') + price_span(product.price) %>
              <%= _('by ') %>

          <% end %>
          <% unless product.price.blank? or product.price == 0 %>

              <%= price_span product.price_with_discount, :class => "product-price #{'with-discount' unless product.discount}" %>
              <%= _(' / ') + (product.unit ? product.unit.singular : _('unit')) %>

          <% end %>

        <% if product.description %>

            <%= _('description') %>

<%= product.description %>

        <% end %>

        <% if product.price_described? %>

            <%= _('price composition') %>

                <% product.inputs.relevant_to_price.each do |i| %>

<%= i.product_category.name %>

                    <%= price_span i.cost, :class => 'search-product-input-price' %>

                <% end %>
                <% product.price_details.each do |i| %>

<%= i.name %>

                    <%= price_span i.price, :class => 'search-product-input-price' %>

                <% end %>

        <% end %>

        <% if product.inputs.count > 0 %>

            <%= _('inputs and raw materials') %>

                <% product.inputs.each do |i| %>

                    <%= _('%{amount_used} %{unit} of') % {:amount_used => i.amount_used, :unit => i.unit.singular} + ' ' if i.has_all_price_details? %>
                    <%= i.product_category.name %>

                <% end %>

        <% end %>

        <% unless product.qualifiers.blank? %>

            <%= _('qualifiers') if product.product_qualifiers.count > 0 %>

<%= render :partial => 'shared/product/qualifiers', :locals => {:product => product} %>

        <% end %>

        <% extra_content_list.map do |content| %>

<%= content %>

        <% end %>

<%= _('product unavailable') unless product.available %>

  <% end %>

<%= pagination_links @products, :params => {:controller => :catalog, :action => :index, :profile => profile.identifier} %>

<%= add_zoom_to_images %>

<% extra_content = [] %>
<% extra_content_list = [] %>

<%= _('Products/Services') %>

<% if @categories %>
  <%= breadcrumb(@category) if params[:level] %>

      <%= content_tag('li', link_to(_('Homepage'), profile.url), :class => 'catalog-categories-link') %>
      <%= content_tag('li', link_to(_('Catalog start'), profile.catalog_url), :class => 'catalog-categories-link') %>
      <% if @categories.present? %>
        <% @categories.each do |category| %>
          <%= category_link(category) %>
          <%= category_sub_links(category) %>
        <% end %>
      <% elsif @category.present? %>
        <%= content_tag('li', _('There are no sub-categories for %s') % @category.name, :id => 'catalog-categories-notice') %>
      <% else %>
        <%= content_tag('li', _('There are no categories available.'), :id => 'catalog-categories-notice') %>
      <% end %>

<% end %>

<ul id="product-list" class="<%="l-sidebar-left-content" if @categories %>">
  <% @products.each do |product| %>
    <% extra_content = @plugins.dispatch(:catalog_item_extras, product).collect { |content| instance_eval(&content) } %>
    <% extra_content_list = @plugins.dispatch(:catalog_list_item_extras, product).collect { |content| instance_eval(&content) } %>

    <% status = [] %>
    <% status << 'not-available' if !product.available %>
    <% status << 'highlighted' if product.highlighted %>

    <li id="product-<%= product.id %>" class="product <%= status.join(' ') %>">

          <% if product.highlighted? %>
            <%= link_to image_tag(themed_path('/images/star.png'), :class => 'star', :alt => _('Highlighted product')), product_path(product) %>
          <% end %>
          <% if product.image %>

              <%= link_to_product product, :class => 'product-big', :style => "background-image: url(#{product.default_image(:big)})" %>
              <%= link_to content_tag(:span, _('Zoom in')), product.default_image(:big).gsub('_big',''), :class => 'zoomify-image' %>

          <% else %>

<%= _('No image') %>

          <% end %>

<%= extra_content.join("\n") %>

<%= link_to_product product %>

          <% unless product.discount.blank? or product.discount == 0 %>

              <%= _('from ') + price_span(product.price) %>
              <%= _('by ') %>

          <% end %>
          <% unless product.price.blank? or product.price == 0 %>

              <%= price_span product.price_with_discount, :class => "product-price #{'with-discount' unless product.discount}" %>
              <%= _(' / ') + (product.unit ? product.unit.singular : _('unit')) %>

          <% end %>

        <% if product.description %>

            <%= _('description') %>

<%= product.description %>

        <% end %>

        <% if product.price_described? %>

            <%= _('price composition') %>

                <% product.inputs.relevant_to_price.each do |i| %>

<%= i.product_category.name %>

                    <%= price_span i.cost, :class => 'search-product-input-price' %>

                <% end %>
                <% product.price_details.each do |i| %>

<%= i.production_cost.name %>

                    <%= price_span i.price, :class => 'search-product-input-price' %>

                <% end %>

        <% end %>

        <% if product.inputs.count > 0 %>

            <%= _('inputs and raw materials') %>

                <% product.inputs.each do |i| %>

                    <%= _('%{amount_used} %{unit} of') % {:amount_used => i.amount_used, :unit => i.unit.singular} + ' ' if i.has_all_price_details? %>
                    <%= i.product_category.name %>

                <% end %>

        <% end %>

        <% unless product.qualifiers.blank? %>

            <%= _('qualifiers') if product.product_qualifiers.count > 0 %>

<%= render :partial => 'shared/product/qualifiers', :locals => {:product => product} %>

        <% end %>

        <% extra_content_list.map do |content| %>

<%= content %>

        <% end %>

<%= _('product unavailable') unless product.available %>

  <% end %>

<%= pagination_links @products, :params => {:controller => :catalog, :action => :index, :profile => profile.identifier} %>

<%= add_zoom_to_images %>