There are two types of modules: you can either create a standard module which displays a list of a new entity type or you can create a blank module which adds functionality. For example, a custom integration with a third-party app. If you do not want an entry in the application navigation sidebar, add "no-sidebar": 1 to the custom module's module.json.
If you're looking for a module to work on you can see suggested issues `listed here <https://github.com/invoiceninja/invoiceninja/issues?q=is%3Aissue+is%3Aopen+label%3A%22custom+module%22>`_.
..NOTE:: Our module implemention is currenty being actively worked on, you can join the discussion on our Slack group: http://slack.invoiceninja.com/
You can extend base views in various ways. Currently, you can:
- dynamically include views on main entity pages by defining a view in the proper namespace and also defining the relation(s) needed on the core entity.
For example, to add fields to the Product model, you define a view in your module at Resources/views/products/edit.blade.php that displays the fields. You then create a new configuration file under Config/ called relations.php with content such as:
The inverse relationship is defined locally in the module entity, e.g. MyProductExtras in the above example.
Settings
""""""""
If your module has settings, you can have them automatically added to the main settings page. To do so, you need to:
- create a Blade template named 'settings.blade.php' under the /Resources folder;
- add whatever routes are needed to implement/save your settings.
..Tip:: You can run the Artisan command ``ninja:make-module-settings`` to generate a stub settings template, and optionally add routes to your module routes.php.
Components
""""""""""
There are UI widgets that can be re-used as part of a custom module implementation.
To render the widget, use the fully-qualified class name anywhere above the @stack declaration:
Depending on the widget, certain variables will need to be passed via the second parameter of the @render statement.
..NOTE:: Any data required by the widget must be passed in @render statement. This means the module developer must ensure to perform any data access in the controller and pass it into the enclosing view.