Skip to content

Commit

Permalink
First batch of the overhaul of the add-ons section
Browse files Browse the repository at this point in the history
  • Loading branch information
sneridagh committed Oct 11, 2024
1 parent b79ef9d commit a16c9ce
Show file tree
Hide file tree
Showing 18 changed files with 1,213 additions and 502 deletions.
68 changes: 68 additions & 0 deletions docs/source/addons/addon-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.

```{info}
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-addon-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

0 comments on commit a16c9ce

Please sign in to comment.