Where to put your code¶
Put all customer-specific code in one plugin named modification_<name>, for example modification_acme, in plugins/easyproject/easy_plugins/.
An Easy8 update replaces the platform, the standard plugins and the engines, so changes made there are lost. Your modification_* plugin is not part of Easy8: carry it over to each new version. Easy8 always activates it and loads it after its own plugins.
What the plugin contains¶
Easy8 treats a directory in plugins/easyproject/easy_plugins/ as a plugin when it has a lib/ directory or a Gemfile. Everything else is optional and picked up by convention:
plugins/easyproject/easy_plugins/modification_acme/
lib/modification_acme.rb # required by the plugin loader, may be an empty module
config/initializers/*.rb # permissions, menus, hooks, settings
config/routes.rb # routes of the plugin
config/locales/*.yml # translations
app/controllers, app/models, # autoloaded, one constant per file
app/views, app/helpers, ...
patches/**/*.rb # changes to existing classes
db/migrate/, db/data/ # migrations
test/spec/ # specs
Minimal lib/modification_acme.rb:
How each part is loaded:
config/initializers/*.rbare required when Easy8 starts. UseEasyInitHelperfor permissions, menus and view hooks, see EasyInitHelper. Existing plugins such aseasy_buttonssplit them into01_access_control.rb,02_menu_manager.rband03_hooks.rb.config/routes.rbis plain routes DSL, withoutRails.application.routes.draw.config/locales/*.ymlare added to the I18n load path.app/viewsis added to the view path. Prefer your own controllers and views. To add a small part to an existing view, use a view hook.- Files in
patches/are required at boot. Register each patch withEasyPatchManager, see Patches. bundle exec rails easy8:installrunsdb/migrateanddb/dataof the plugin. Follow the migration rules.
What not to change¶
Do not edit files in the Redmine core, in easy_engines/ or in other plugins. To change their behaviour, patch them from your plugin.
Every change outside your plugin must be re-applied after each update, and a merge conflict is likely.
Deploy the plugin¶
Docker installation¶
Keep the plugin folder next to docker-compose.yml and mount it into the app and sidekiq containers with a docker-compose.override.yml in the same folder. Docker Compose reads the override file automatically, and an Easy8 update does not replace it.
services:
app:
volumes:
- ./modification_acme:/opt/easy/current/plugins/easyproject/easy_plugins/modification_acme:ro
sidekiq:
volumes:
- ./modification_acme:/opt/easy/current/plugins/easyproject/easy_plugins/modification_acme:ro
Run the plugin's migrations and restart Easy8:
- The containers run as user 5000, so that user must be able to read the plugin files.
- If you start Easy8 with
-foptions, Compose does not load the override file by itself; add-f docker-compose.override.yml. - The image contains precompiled frontend assets. A mounted plugin can add Ruby code, views, translations, routes and migrations, but no stylesheets or scripts that Easy8 compiles. Those have to be built into the image, see Build image in the Docker guide. Branding needs no build, see Branding on Docker.
After an update, the new image picks up the same mount. Run docker compose run --rm app install again.
Source installation¶
Copy the plugin folder to plugins/easyproject/easy_plugins/ and run the installer:
If the plugin has stylesheets or scripts, rebuild the assets with RAILS_ENV=production bundle exec rails assets:precompile, then restart Easy8. After an update, copy the folder into the new version and repeat these steps.