Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First batch of the overhaul of the add-ons section #6397

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added docs/source/_static/plone-home-page.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
68 changes: 68 additions & 0 deletions docs/source/addons/add-on-configuration-pipeline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
myst:
html_meta:
"description": "Add-on and project configuration pipeline"
"property=og:description": "Add-on and project configuration pipeline"
"property=og:title": "Add-on and project configuration pipeline"
"keywords": "Volto, Plone, Volto add-ons, Volto Project"
---
%Explanation
# Add-on and project configuration pipeline

Volto build its configuration out of Volto's configuration defaults, add-ons configuration, and project configuration.
This is called the configuration pipeline.

![Volto configuration pipeline](./configuration-pipeline.png)

It's applied in this particular order.
Configurations can be overriden at a later stage.

## All-in with add-on approach

You can take full advantage of the configuration pipeline and do not use the project configuration at all.
You can create a "policy" core product for your project, and use another for your project's theme.
This way, the project itself renders as a simple boilerplate, expendable or rebuild-able at any time.
You can also reuse add-ons across projects, and adjust them using another add-ons, depending on the other projects requirements.

```{deprecated} Volto 18.0.0
The project configuration approach is deprecated and will be removed in Volto 19.
```

## Define your add-ons programatically

Having the `addons` key in `package.json` is not flexibile enough in complex scenarios.
You can load your add-ons programatically, outside `package.json` using `volto.config.js` like this:

```js
module.exports = {
addons: ['@eeacms/volto-accordion-block']
}
```

This is an "escape hatch" where you can use logic and environment conditions to define the add-ons to be loaded in the current project. Take a look:


```js
let addons = [];
if (process.env.MY_SPECIAL_ENV_VAR) { // Does not have to be RAZZLE_
addons = ['volto-my-awesome-special-add-on'];
}

if (process.env.MARKER_FOR_MY_SECRET_PROJECT) { // Does not have to be RAZZLE_
addons = [
'@kitconcept/volto-heading-block',
'@kitconcept/volto-slider-block',
'volto-my-secret-project-add-on',
];
}

module.exports = {
addons: addons,
};
```

They are added to the existing ones in `package.json`.

```{seealso}
{doc}`../configuration/volto-config-js`
```
Binary file added docs/source/addons/configuration-pipeline.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
118 changes: 118 additions & 0 deletions docs/source/addons/how-an-add-on-works.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
---
myst:
html_meta:
"description": "How does a Volto add-on work?"
"property=og:description": "How does a Volto add-on works?"
"property=og:title": "How does a Volto add-on works?"
"keywords": "Volto, Plone, Volto add-ons, JavaScript, JavaScript dependencies"
---
% Explanation
# How does a Volto add-on work?

Volto add-on packages are just CommonJS/ESM packages.
Their main purpose is encapsulate logic, configuration and customizations in a reusable way.
The only requirement is that they point the `main` key of their `package.json` to a module that exports, as a default function that acts as a Volto configuration loader.

Similarly to how you develop a Plone backend Python add-on, you can control all aspects of Volto from a Volto add-on.

This gives you the ability to move all your project configuration, components, customizations and even theme files to an add-on.
This has the advantage to render the project configuration empty and expendable, so you could at any point not only reuse the add-on(s) outside the current project, but also have the project as simply boilerplate that could be replaced at any point (for example, a Volto version upgrade).

An add-on can be published in an npm registry, just as any other package.
However, Volto add-ons should not be transpiled.
They should be released as "source" packages.

See [@kitconcept/volto-button-block](https://github.com/kitconcept/volto-button-block) as an example.

## Add-on configuration

The default export of your add-on main `index.js` file should be a function with
the signature `config => config`.
That is, it should take the `global` configuration object and return it, possibly mutated or changed.
So your main `index.js` will look like:

```js
export default function applyConfig(config) {
config.blocks.blocksConfig.faq_viewer = {
id: 'faq_viewer',
title: 'FAQ Viewer',
edit: FAQBlockEdit,
view: FAQBlockView,
icon: chartIcon,
group: 'common',
restricted: false,
mostUsed: true,
sidebarTab: 1,
security: {
addPermission: [],
view: [],
},
};
return config;
}
```

And the `package.json` file of your add-on:

```json
{
"main": "src/index.js",
}
```

In effect, Volto does the equivalent of:

```
import installMyVoltoAddon from 'my-volto-addon'

// ... in the configuration registry setup step:
const configRegistry = installMyVoltoAddon(defaultRegistry);
```

So the Volto add-on needs to export a default function that receives the Volto configuration registry, is free to change the registry as it sees fit, then it needs to return that registry.

Volto will chain-execute all the add-on configuration functions to compute the final configuration registry.

```{note}
An add-on's default configuration method will always be loaded.
```

### Providing optional add-on configurations

You can export additional configuration functions from your add-on's main
`index.js`.

```js
import applyConfig, {loadOptionalBlocks,overrideSomeDefaultBlock} from './config';

export { loadOptionalBlocks, overrideSomeDefaultBlock };
export default applyConfig;
```

```{seealso}
{doc}`how-to-load-add-on-configuration`
```

## Customizations

Add-on packages can include customization folders, just like the Volto projects.
The customizations are resolved in the order: add-ons (as sorted in the `addons` key of your project's `package.json`) then the customizations in the Volto project, last one wins.

```{tip}
See the {ref}`advanced-customization-scenarios-label` section on how to enhance this pattern and how to include customizations inside add-ons.
```

## Add-on dependencies

Add-ons can depend on any other JavaScript package, but they can also depend on other Volto add-ons.
To do this, specify the name of your Volto add-on dependency in your `dependencies` key of `package.json` and create a new `addons` key in the `package.json` of your add-on, where you specify the extra Volto add-on dependency.

By doing this, the add-ons can "chain-load" one another, so you don't have to keep track of intermediary dependencies.

```json
{
"name": "volto-slate",

"addons": ["@eeacms/volto-object-widget"]
}
```
Loading
Loading