Project

General

Profile

Porting plugin: No redmine at all!

Added by Jiří Křivánek over 11 years ago

Hello,

I spend more than 18 hours on attempts to port my existing Redmine plugins from 1.3 to 2.0. I was able to fix tons of problems but it still does not work. It makes me crazy...

I read what I could here, I did the cross compare with the other plugins downloaded from here and said to support Redmine 2.0. Cannot find any problem, please help!

My redime is this:

My plugin looks like this - no Redmine in the plugin surrounding (not even the HTML headers in the page source code)!!!

I am not attaching any sources yet, as I expect someone to kick me that I am doing some very very basic error...


Replies (7)

RE: Porting plugin: No redmine at all! - Added by Etienne Massip over 11 years ago

Without any code, it's hard to tell =)

RE: Porting plugin: No redmine at all! - Added by Jiří Křivánek over 11 years ago

No problem - see attached - it is complete this time...

RE: Porting plugin: No redmine at all! - Added by Jiří Křivánek over 11 years ago

BTW: I also tried one of the plugins which are said to be compatible with 2.0. And yes it works.

RE: Porting plugin: No redmine at all! - Added by Jiří Křivánek over 11 years ago

For the convenience, I am also adding a few fragments into text:

init.rb

require 'redmine'

Redmine::Plugin.register :redmine_kk_works do
  name 'KkWorks plugin'
  author 'Jiri Krivanek'
  description 'This plugin improves the spent time recording and adds the simple reporting on it'
  version '0.0.5'

  permission :kkworks_view_works,
             :kk_works => [:index, :history_depth]

  permission :kkworks_edit_works,
             :kk_works => [:index, :delete, :edit, :entry, :save_edit, :history_depth]

  permission :kkworks_view_self_report,
             :kk_works => [:index, :report]

  permission :kkworks_view_others_report,
             :kk_works => [:index, :report]

  menu :top_menu, :kk_works, { :controller => 'kk_works', :action => 'index' }, :caption => :menu_item_caption,
       :if => Proc.new { User.current.logged? && (User.current.allowed_to?(:kkworks_view_works, nil, {:global => true}) || User.current.allowed_to?(:kkworks_edit_works, nil, {:global => true}) || User.current.allowed_to?(:kkworks_view_self_report, nil, {:global => true}) || User.current.allowed_to?(:kkworks_view_others_report, nil, {:global => true})) }
end

routes.rb

match 'kk_works/index', :to => 'kk_works#index'
match 'kk_works/entry', :to => 'kk_works#entry'
match 'kk_works/history_depth', :to => 'kk_works#history_depth'
match 'kk_works/report', :to => 'kk_works#report'

index.html.erb - just a few first rows...

<% html_title l(:menu_item_caption) %>

<div class="contextual">
    <%
    user_form = "user_select_form" 
    onSelectChanged = "return " + user_form + ".submit();" 
    %>
    <%= form_tag({:controller => 'kk_works', :action => 'history_depth'}, {:name => user_form}) do %>
    <table><tr>
    <% 
        if @can_view_others_reports
            user_items = []
            users = User.find(:all, :conditions => {:users => {:status => User::STATUS_ACTIVE}}, :order => "lastname, firstname")
            users.each { |user| user_items << [user.lastname + ' ' + user.firstname, user.id] }
    %>
            <td nowrap="nowrap" align="right" valign="middle">
            <%= l(:selected_user) %>
            </td>
            <td nowrap="nowrap" align="right" valign="middle">
            <%= select_tag(:user_id, options_for_select(user_items, @user_id), {:onchange => onSelectChanged}) %>
            </td>
    <% 
        end
.........

kk_works_controller.rb - just a few first rows...

require 'time.rb'

AT_ONLY_LEVEL_0 = 0
AT_ONLY_LEVEL_01 = 1
AT_ALL_LEVELS = 2
AT_ALSO_TASKS = 3

class KkWorksController < ApplicationController
    unloadable
    before_filter :authorize_global
    before_filter :ensure_permissions

    def initialize

        # Diary

        @spent_on_s = Date.today.to_s
        @time_from_s = ''
        @time_to_s = ''
        @issue_id_s = ''
        @activity_id = ''
        @comments = ''
        @error_text = []
        @editing_id = nil
        @history_depth = 1 # Week

        # Report 

        @alsoTasks = AT_ALL_LEVELS
        @user_kind = "U" 
        @user_id = User.current.id

        @intervalMethod = "monthYear" 

        @month = 1
        @year = 2011

        @dateFrom = nil
        @dateFrom_s = "" 
        @dateTo = nil
        @dateTo_s = "" 
    end

    def ensure_permissions()
        @can_view_works = !!User.current.allowed_to?(:kkworks_view_works, nil, {:global => true})
        @can_edit_works = !!User.current.allowed_to?(:kkworks_edit_works, nil, {:global => true})
        @can_view_self_reports = !!User.current.allowed_to?(:kkworks_view_self_report, nil, {:global => true})
........
    def index
        # Ensure the history depth from the session
        if session.has_key?(:kk_works_history_depth)
            @history_depth = session[:kk_works_history_depth]
        end
        # Ensure the selected user ID from the session
        if session.has_key?(:kk_works_diary_user_id) && @can_view_others_reports
            @user_id = session[:kk_works_diary_user_id]
        else
            session[:kk_works_diary_user_id] = @user_id = User.current.id
        end
    end
........

RE: Porting plugin: No redmine at all! - Added by Etienne Massip over 11 years ago

You're overriding ApplicationController#initialize without calling superclass constructor.

RE: Porting plugin: No redmine at all! - Added by Jiří Křivánek over 11 years ago

Great, that is exactly what I expected to happen - just a stupid error resulting from the lack of info - now it works...

Unfortunately, my problems are:
  1. I am writing the Redmine plugins without any deep knowledge of neither Ruby nor Rails nor Redmine (I simply have no time and brain capacity to learn completely new technology).
  2. The old plugins did not need to do call the supe constructor.
  3. I was not able to find anywhere noted that the constructors approach has changed.
  4. Most of the existing Redmine plugins do not override the controller constructor, so I was not able to see it in those few I downloaded and studied for reference.

Well, thank you, since you adviced me, it was just a piece of cake - both my plugins are ready for Redmine 2(.0.3 - hopefully, you will not do such a significant changes in a real future)!

For the others, I am adding one more hint which I was not able to find in any Redmine Wiki pages (but I easily found it on Google):
  • The JSON encoding/decoding has also changed.
    1. Different class.
    2. Different functionality - now "1" is not a valid JSON object (it throws something like JSON string must be at least two octets).

RE: Porting plugin: No redmine at all! - Added by Etienne Massip over 11 years ago

Jiří Křivánek wrote:

Unfortunately, my problems are:
  1. I am writing the Redmine plugins without any deep knowledge of neither Ruby nor Rails nor Redmine (I simply have no time and brain capacity to learn completely new technology).
  2. The old plugins did not need to do call the supe constructor.
  3. I was not able to find anywhere noted that the constructors approach has changed.
  4. Most of the existing Redmine plugins do not override the controller constructor, so I was not able to see it in those few I downloaded and studied for reference.

In RoR, you should prefer using before_filter rather than a constructor.
As a general rule, whichever is the language, when you're overriding a method you might want to call the superclass method unless you want to fully replace its behavior.

Well, thank you, since you adviced me, it was just a piece of cake - both my plugins are ready for Redmine 2(.0.3 - hopefully, you will not do such a significant changes in a real future)!

Not until RM 3 for Rails 4, I guess.

  1. Different functionality - now "1" is not a valid JSON object (it throws something like JSON string must be at least two octets).

Rails is now less permissive; a number is indeed not a JSON object.

    (1-7/7)