Prepare for Redmine 6! Checklist for Adapting Themes and Plugins
On November 11, 2024, Redmine 6.0.0 was released, incorporating the fix at r23173. As a result, the actions described in [1.2 The relative path of `application.css` for `import` in themes will change] are no longer necessary.
Overview
- The installation directory for themes will change from
public/themes
tothemes
. - The relative path of
application.css
forimport
in themes will change. - The base class for models will change from
ActiveRecord::Base
toApplicationRecord
.
With the upcoming major release of Redmine 6, there will be several changes impacting themes and plugins along with an upgrade to Ruby on Rails version 7. This article provides detailed explanations of the necessary preparations to adapt to these changes.
This article is based on the code from Redmine r22781 (trunk)
.
Future developments may introduce changes, so please check for the latest information at that time.
Table of Contents
1. Themes
1.1 The installation directory for themes will change from public/themes
to themes
Affected Themes: All themes except Default, Alternate, and Classic.
When the asset pipeline library was changed from Sprockets to Propshaft in Feature #39111: Enable Asset Pipeline Integration using Propshaft - Redmine, the installation directory for themes was also changed.
Previously, themes were located in public/themes
and plugins in plugins
.
Starting with Redmine 6, themes will be in themes
and plugins in plugins
, creating a more intuitive directory structure.
When updating to Redmine 6, check the documentation of the theme you are using for compatibility and follow the provided steps for reinstallation if necessary.
Note: Although the asset pipeline library has changed from Sprockets to Propshaft, there is generally no need to manually run the rake assets:precompile
command.
Redmine will automatically check if asset updates are needed and compile them as necessary.
1.2 The relative path of application.css
for import
in themes will change
On November 11, 2024, Redmine 6.0.0 was released, incorporating the fix at r23173. As a result, the actions described in this section are no longer necessary.
Affected Themes: Almost all themes except Default, Alternate, and Classic (with some exceptions depending on the theme's structure).
This issue arises due to changes in the relationship between the theme directory and the placement of application.css
in Feature #39111: Enable Asset Pipeline Integration using Propshaft - Redmine.
An example of display issues when using the unsupported "Bleuclair" theme.
If you use unsupported themes in Redmine 6, you may encounter display issues like this.
"How to create a custom Redmine theme" at April 16, 2024
Redmine themes typically import the standard application.css
and apply CSS to override it.
Due to the introduction of Propshaft, the relationship between the theme directory and the placement of Redmine's standard application.css
will change, so you need to change
@import url(../../../stylesheets/application.css);
to
@import url(../../application.css);
Furthermore, a compatible solution has not yet been found.
You need to switch files by using repository branches or tags, for versions prior to Redmine 5:
@import url(../../../stylesheets/application.css);
for Redmine 6 and later:
@import url(../../application.css);
(If you have any good ideas for a compatible solution, please let us know!)
When updating to Redmine 6, check the documentation of the theme you are using to ensure it is compatible with Redmine 6. If it is compatible and includes instructions for changes, follow those steps to reinstall if necessary.
2. Plugins
2.1 The base class for models will change from ActiveRecord::Base
to ApplicationRecord
Affected Plugins: Plugins that have custom model classes under the /app/models
directory, especially those using acts_as_****
functionalities.
Due to the changes in Patch #38975: Use ApplicationRecord instead of ActiveRecord::Base - Redmine, the inheritance for models written as:
class ModelName < ActiveRecord::Base
will change to:
class ModelName < ApplicationRecord
Using ApplicationRecord
has become common practice since Rails 5, but Redmine had not adopted this until now. This change addresses that issue.
Source: ApplicationRecord in Rails 5 - BigBinary Blog
But now, ActiveRecord::Base forever includes MyAwesomeFeature and any class inheriting from it also includes MyAwesomeFeature even if they don't want it.
This is especially true if you are using plugins and engines where monkey patching to ActiveRecord::Base can leak into engine or plugin code.
But with ApplicationRecord, they will be localized to only those models which are inheriting from ApplicationRecord, effectively only to your application.
As the citation suggests, by making the ApplicationRecord
class that inherits from ActiveRecord::Base
the base class for models, it prevents customizations to the model from unintentionally affecting other areas (such as engines).
For plugins that create custom model classes under app/models
, it is essential to address the changes if they use any of the functionalities listed below. Even if there are no immediate issues, it is recommended to make these adjustments to keep up with future changes in Redmine.
- redmine/app/models/application_record.rb at 1c17ae7 · redmine/redmine · GitHub
- Overriding the
human_attribute_name
method has been changed to apply toApplicationRecord
instead ofActiveRecord::Base
. If the base class remainsActiveRecord::Base
, the behavior of thehuman_attribute_name
method may change.
- Overriding the
- redmine/lib/plugins/actsasactivity_provider/init.rb at 1c17ae7 · redmine/redmine · GitHub
- When using functionalities like
acts_as_xxxxx
(e.g.,acts_as_positioned
),acts_as_xxxxx
is now included inApplicationRecord
instead ofActiveRecord::Base
. Therefore, if the base class remainsActiveRecord::Base
,acts_as_xxxxx
will not be found and an exception will occur.
- When using functionalities like
Simply replacing ActiveRecord::Base
with ApplicationRecord
will cause compatibility issues with Redmine versions prior to 5. Therefore, it is better to check for the existence of the class and decide which class to inherit from accordingly, as shown below.
class ModelName < (defined?(ApplicationRecord) == 'constant' ? ApplicationRecord : ActiveRecord::Base) ... end
Example: https://github.com/agileware-jp/redmine_issue_templates/issues/95