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

IBX-6404: Added create bundle extension #2214

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 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/administration/img/bundle_generator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/administration/img/bundle_page_block.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/administration/img/new_tag.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/administration/img/packagist_submit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/administration/img/sys_info_composer_tab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
---

Check warning on line 1 in docs/administration/project_organization/bundle_extension/create_bundle.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/administration/project_organization/bundle_extension/create_bundle.md#L1

[Ibexa.ReadingLevel] The grade level is 8.46. Aim for 8th grade or lower by using shorter sentences and words.
Raw output
{"message": "[Ibexa.ReadingLevel] The grade level is 8.46. Aim for 8th grade or lower by using shorter sentences and words.", "location": {"path": "docs/administration/project_organization/bundle_extension/create_bundle.md", "range": {"start": {"line": 1, "column": 1}}}, "severity": "WARNING"}
description: Create a bundle extension for Ibexa DXP.
---

# Create bundle

A bundle is a reusable [[= product_name =]] extension that can be integrated.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about...
"Bundles are reusable [==] extensions that can be integrated"?
This would help get rid of the articles.

To ensure full compatibility, follow the structure specifications described in the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
To ensure full compatibility, follow the structure specifications described in the
When creating your own bundle, to ensure full compatibility, follow the structure specifications described in the

[package structure](package_structure.md/#package-and-bundle-structure-and-namespaces) section.

The bundle extension described here is called `AcmeCurrencyExchangeRate` and enables a new page block which displays a currency exchange rate on your site.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The bundle extension described here is called `AcmeCurrencyExchangeRate` and enables a new page block which displays a currency exchange rate on your site.
The bundle extension described here is called `AcmeCurrencyExchangeRate` and enables a new page block which displays a currency exchange rate.


You can create a bundle skeleton in two simplified ways:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can create a bundle skeleton in two simplified ways:
You can create a bundle skeleton in two ways:


- [using Ibexa bundle generator](#create-bundle-with-bundle-generator)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- [using Ibexa bundle generator](#create-bundle-with-bundle-generator)
- [with [[= product_name_base =]] bundle generator](#create-bundle-with-bundle-generator)

- [with GitHub template](#use-github-template)

Check warning on line 16 in docs/administration/project_organization/bundle_extension/create_bundle.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/administration/project_organization/bundle_extension/create_bundle.md#L16

[Ibexa.ThirdPartyNames] Use 'GitHub' instead of 'github'
Raw output
{"message": "[Ibexa.ThirdPartyNames] Use 'GitHub' instead of 'github'", "location": {"path": "docs/administration/project_organization/bundle_extension/create_bundle.md", "range": {"start": {"line": 16, "column": 31}}}, "severity": "WARNING"}

## Create bundle with bundle-generator
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Create bundle with bundle-generator
## Create bundle with bundle generator


[[= product_name_base =]] bundle generator is a Symfony Bundle generator for projects based on [[= product_name =]].
It can work as a standalone application mode.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
It can work as a standalone application mode.
It can work in a standalone application mode.

This section thoroughly explains how to create a bundle using generator as a stand-alone application.
You can use this skeleton as a basis for your extension project.
It's the easiest and recommended way.
Comment on lines +22 to +24
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This section thoroughly explains how to create a bundle using generator as a stand-alone application.
You can use this skeleton as a basis for your extension project.
It's the easiest and recommended way.
Create a bundle by using the generator as a stand-alone application.
It's the easiest and recommended way, and you can use the skeleton as a basis for your extension project.


1\. Go to [Ibexa bundle generator](https://github.com/ibexa/bundle-generator){:target="\_blank"} and clone the repository.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1\. Go to [Ibexa bundle generator](https://github.com/ibexa/bundle-generator){:target="\_blank"} and clone the repository.
1\. Go to the Ibexa bundle generator [GitHub repository](https://github.com/ibexa/bundle-generator){:target="\_blank"} and clone it:


```bash
git clone [email protected]:ibexa/bundle-generator.git

Check warning on line 29 in docs/administration/project_organization/bundle_extension/create_bundle.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/administration/project_organization/bundle_extension/create_bundle.md#L29

[Ibexa.ThirdPartyNames] Use 'GitHub' instead of 'github'
Raw output
{"message": "[Ibexa.ThirdPartyNames] Use 'GitHub' instead of 'github'", "location": {"path": "docs/administration/project_organization/bundle_extension/create_bundle.md", "range": {"start": {"line": 29, "column": 15}}}, "severity": "WARNING"}
```
2\. Change to bundle generator directory.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
2\. Change to bundle generator directory.
2\. Go the the bundle generator's local directory:


```bash
cd bundle-generator
```

3\. Install dependencies:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
3\. Install dependencies:
3\. Install the dependencies:


```bash
composer install
```

4\. Run bundle generator:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
4\. Run bundle generator:
4\. Run the bundle generator:


```bash
php bin/ibexa-bundle-generator currency-exchange-rate --skeleton-name=extension
```

5\. Adjust the bundle to your needs providing the following parameters.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
5\. Adjust the bundle to your needs providing the following parameters.
5\. Adjust the bundle to your needs by providing the following parameters.

The command runs with an interactive mode.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The command runs with an interactive mode.
The command runs in interactive mode.


- Package vendor name - acme
- Bundle vendor namespace - Acme
- Bundle name - CurrencyExchangeRate
- Skeleton name - acme-ee

![Bundle generator](bundle_generator.png)

This creates a bundle files structure in the  `./target` directory.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This creates a bundle files structure in the  `./target` directory.
This creates the bundle's file structure in the  `./target` directory.


You can rename the target directory according to your needs.

You can also use a command with all available options:


```bash
php bin/ibexa-bundle-generator currency-exchange-rate currency-exchange-rate-dir  --vendor-name=acme --vendor-namespace=ACME --bundle-name=CurrencyExchangeRate  --skeleton-name=extension
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
php bin/ibexa-bundle-generator currency-exchange-rate currency-exchange-rate-dir  --vendor-name=acme --vendor-namespace=ACME --bundle-name=CurrencyExchangeRate  --skeleton-name=extension
php bin/ibexa-bundle-generator currency-exchange-rate currency-exchange-rate-dir --vendor-name=acme --vendor-namespace=ACME --bundle-name=CurrencyExchangeRate --skeleton-name=extension

```

## Create bundle with GitHub template

1\. Go to the [[= product_name_base =]] [GitHub repository](https://github.com/ibexa/bundle-template).

2\. In the upper-right corner, click the **Use this template** button, and select **Create a new repository**.

3\. Provide repository name. Optionally, you can add description for the bundle.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
3\. Provide repository name. Optionally, you can add description for the bundle.
3\. Provide the repository name. Optionally, you can add a description for the bundle.

Next, click **Create repository**.
juskora marked this conversation as resolved.
Show resolved Hide resolved

![GitHub template](bundle_github_template.png)
Once the repository is created, a workflow starts and generates the bundle structure.
juskora marked this conversation as resolved.
Show resolved Hide resolved

Vendor namespace is generated from the orgnization name.
Package and bundle name inherits from repository name.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Package and bundle name inherits from repository name.
Package and bundle name inherits from the repository name.

### Bundle directory structure
juskora marked this conversation as resolved.
Show resolved Hide resolved

Generated bundle consists of the following structure:

```

Check failure on line 88 in docs/administration/project_organization/bundle_extension/create_bundle.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/administration/project_organization/bundle_extension/create_bundle.md#L88

[Ibexa.CodeBlockLanguages] Always provide a language with a code block.
Raw output
{"message": "[Ibexa.CodeBlockLanguages] Always provide a language with a code block.", "location": {"path": "docs/administration/project_organization/bundle_extension/create_bundle.md", "range": {"start": {"line": 88, "column": 1}}}, "severity": "ERROR"}
.
├── LICENSE
├── README.md
├── composer.json
├── deptrac.yaml
├── package.json
├── phpstan.neon
├── phpunit.xml.dist
├── src
│   ├── bundle
│   │   ├── AcmeCurrencyExchangeRateBundle.php
│   │   ├── DependencyInjection
│   │   │   └── AcmeCurrencyExchangeRateExtension.php
│   │   └── Resources
│   │   ├── config
│   │   │   ├── prepend.yaml
│   │   │   ├── services
│   │   │   └── services.yaml
│   │   └── views
│   │   └── themes
│   │   ├── admin
│   │   └── standard
│   ├── contracts
│   └── lib
└── tests
├── bundle
├── integration
└── lib
```
Where:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Where:
Where file structure elements are as follows:

Also, I am not sure whether the bullets below should have fullstops. We're not consistent in this matter but in most cases enumerations like this have no fullstops at line ends


- `LICENSE` - a license file, GPL v2 by default.
- `README.md` - a readme file with bundle description, its version and install instructions.
- `composer.json` - a package definition.
- `deptrac.yaml` - a tool for static code analysis for PHP, checks the coherence of package architecture, for more information see [deptrac](https://qossmic.github.io/deptrac/) documentation.
- `package.json` - frontend dependencies, for more information, see [about packages and modules](https://docs.npmjs.com/about-packages-and-modules).
- `phpstan.neon` - phpstan configuration, a tool for static code analysis for PHP, scans, and evaluates codebase to find errors, and bugs, for more information, see the [documentation](https://phpstan.org/user-guide/getting-started).
- `phpunit.xml.dist` - config for phpunit, unit and integration tests - see [documentation](https://phpunit.de/getting-started/phpunit-10.html).
- `src` and `tests` follow the base catalog structure, according to [package structure](https://phpunit.de/getting-started/phpunit-10.html) docs.

To fully use the possibilities of the bundle, get familiar with the structure:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
To fully use the possibilities of the bundle, get familiar with the structure:
To use full advantage of the bundle, get familiar with the structure:

Same comment about fullstops as before


- `resources/`
- `config/` - contains configuration for the environment and governs budle configuration.
- `services/` - recommended place for services definition files, all services definitions must be split into separate files.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- `services/` - recommended place for services definition files, all services definitions must be split into separate files.
- `services/` - recommended place for service definition files, individual service definitions must be split into separate files.

- `prepend.yaml` - houses additional configuration for other extensions.
- `views/` - handles the [design engine](../../../templating/design_engine/design_engine.md).
- `tests` - contains all tests for the bundle. For more information, see [continuous integration](#continuous-integration).

## Build page block

This section presents an example of how to create an extension that adds a new page block to Page Builder.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This section presents an example of how to create an extension that adds a new page block to Page Builder.
Create an extension that adds a new page block to Page Builder.


1\. In `composer.json` add the Page Builder depency to be able to create a page block:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1\. In `composer.json` add the Page Builder depency to be able to create a page block:
1\. In `composer.json`, add the Page Builder dependency to be able to create a page block:


```json
"require": {
"php": "^7.4 || ^8.0",
"ibexa/core": "^4.5",
"ibexa/page-builder": "^4.5",
"symfony/config": "^5.4",
"symfony/dependency-injection": "^5.4",
"symfony/event-dispatcher": "^5.4",
"symfony/event-dispatcher-contracts": "^2.2",
"symfony/http-foundation": "^5.4",
"symfony/http-kernel": "^5.4",
"symfony/yaml": "^5.4",
"http-interop/http-factory-guzzle": "^1.2"
},
```

2\. Page Builder isn't an open-source package, so to be able to use this dependency, add `repositories`:

```json
"repositories": {
"ibexa": {
"type": "composer",
"url": "https://updates.ibexa.co"
}
}
```

3\. Next, run the following command to fetch the Page Builder dependency:

```bash
composer update
```

For more information, see [bundles documentation](../../../administration/project_organization/bundles.md).

Comment on lines +180 to +181
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For more information, see [bundles documentation](../../../administration/project_organization/bundles.md).
For more information, see [Bundles](../../../administration/project_organization/bundles.md).


### Create bundle example

!!! note

Make sure you follow naming convention to ensure clarity.

Comment on lines +187 to +188
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Make sure you follow naming convention to ensure clarity.
Make sure you follow the naming convention to ensure clarity.


### Define block

Define specific settings for the page block bundle. Files should follow the Symfony configuration convention. Define various aspects of the bundle, include services, parameters, routess, and security.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Define specific settings for the page block bundle. Files should follow the Symfony configuration convention. Define various aspects of the bundle, include services, parameters, routess, and security.
Define specific settings for the page block bundle.
Make sure files follow the Symfony configuration convention.
Define various aspects of the bundle, include services, parameters, routes, and security.


To define a page block, in the `prepend.yaml` file, add the following page block configuration:

```yaml
ibexa_fieldtype_page:
blocks:
currency_exchange:
name: Currency exchange
thumbnail: /assets/images/blocks/random_block.svg#random
views:
default:
template: '@ibexadesign/blocks/currency_exchange/default.html.twig'
name: Currency exchange block
attributes:
amount:
type: integer
name: Amount
base_currency:
type: select
name: Base currency
options:
choices:
'US Dollar': USD
'EURO': EUR
'Polish Zloty': PLN
```
This file contains all configuration provided for 3rd party extension packages.

### Implement view

Create a view template that you indicated in the configuration.
In the `src`, add the `default.html.twig` file with the script provided by [Currency rate](https://currencyrate.today/exchangerates-widget):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In the `src`, add the `default.html.twig` file with the script provided by [Currency rate](https://currencyrate.today/exchangerates-widget):
In `src`, add the `default.html.twig` file with the script provided by [Currency rate](https://currencyrate.today/exchangerates-widget):


```html+twig
<script>var fm = "{{ base_currency }}";
var to = "BTC,AUD,GBP,EUR,CNY,JPY,RUB";
var tz = "timezone";
var sz = "1x349";
var lg = "en";var st = "primary";
var cd = 0;
var am = {{ amount }}</script><script src="//currencyrate.today/exchangerates"></script>
<div style="text-align:right"><a href="https://currencyrate.today">CurrencyRate</a></div>
```

Next, commit all changes to the GitHub.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Next, commit all changes to the GitHub.
Next, commit all changes to GitHub.


### Continuous integration

To ensure quality requirements of your code in the newly created bundle, run:

- `composer php cs fixer`
- `composer tests`

Before releasing the newly created bundle, ensure your source meets quality requirements by running:
- run composer php cs fixer
- run composer test unit tests
Comment on lines +247 to +248
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- run composer php cs fixer
- run composer test unit tests
- `run: composer php-cs-fixer`
- `run composer test:unit tests`


[GitHub actions](https://docs.github.com/en/actions)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like parto of the sentence is missing?


To ensure delivery of working code, use CI/CD pipeline right from the GitHub repository.

Best practices for testing your bundle encompas:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Best practices for testing your bundle encompas:
Best practices for bundle testing include:


- supported Symfony versions
- supported PHP versions
- unit tests

## License and readme

Before you publish the bundle, choose the license type and modify the readme file according to your needs.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---

Check warning on line 1 in docs/administration/project_organization/bundle_extension/install_package.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/administration/project_organization/bundle_extension/install_package.md#L1

[Ibexa.ReadingLevel] The grade level is 5.47. Aim for 8th grade or lower by using shorter sentences and words.
Raw output
{"message": "[Ibexa.ReadingLevel] The grade level is 5.47. Aim for 8th grade or lower by using shorter sentences and words.", "location": {"path": "docs/administration/project_organization/bundle_extension/install_package.md", "range": {"start": {"line": 1, "column": 1}}}, "severity": "WARNING"}
description: Install created bundle extension into Ibexa DXP.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description: Install created bundle extension into Ibexa DXP.
description: Install a bundle extension you created into Ibexa DXP.

---

# Install bundle

## Add repository to composer


To be able to install the bundle in your [[= product_name_base =]] project, add the repository to the `composer.json`:
Comment on lines +9 to +10
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
To be able to install the bundle in your [[= product_name_base =]] project, add the repository to the `composer.json`:
To install the bundle in your [[= product_name_base =]] project, add the repository to `composer.json`:


```json hl_lines="17"
"repositories": {
"ibexa": {
"type": "composer",
"url": "https://updates.ibexa.co"
},
"acme/currency-exchange-rate":{
"type": "vcs",
"url": "file:///Users/justyna.koralewicz/example-3rd-party-extension"
}
}
```

## Install bundle into application

On your [[= product_name_base =]] project root run:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
On your [[= product_name_base =]] project root run:
In your [[= product_name_base =]] project root directory, run:


```bash
composer require acme/currency-exchange-rate:dev-main
```

!!! note

If your application uses Symfony Flex, the bundle is registered automatically after you install it.
Check whether the bundle is enabled, if not, you must enable it per environment in the `config/bundles.php` file:
Comment on lines +35 to +36
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If your application uses Symfony Flex, the bundle is registered automatically after you install it.
Check whether the bundle is enabled, if not, you must enable it per environment in the `config/bundles.php` file:
If your application uses Symfony Flex, the bundle is registered automatically after you install it.
Check whether the bundle is enabled.
If not, you must enable it per environment in the `config/bundles.php` file:

```php
juskora marked this conversation as resolved.
Show resolved Hide resolved
return [
    Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
    ...
    Ibexa\Bundle\TestFixtures\IbexaTestFixturesBundle::class => ['all' => true],
    ACME\Bundle\CurrencyExchangeRate\ACMECurrencyExchangeRateBundle::class => ['all' => true],
];
```
Next, clear the cache by runnig the following command:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Next, clear the cache by runnig the following command:
Next, clear the cache by running the following command:


```bash
php bin/console cache:clear
```

The newly installed bundle should be visible in the **Composer** tab in **Admin** -> **System information**.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The newly installed bundle should be visible in the **Composer** tab in **Admin** -> **System information**.
The newly installed bundle should be visible in **Admin** -> **System information** -> **Composer** tab.


![Installed bundles](sys_info_composer_tab.png)
## Add currency exchange page block
juskora marked this conversation as resolved.
Show resolved Hide resolved

Go to Page Builder edit mode. The Currency exchange block should be visible and available in the **Elements** panel.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Go to Page Builder edit mode. The Currency exchange block should be visible and available in the **Elements** panel.
Go to Page Builder edit mode.
The Currency exchange block should be visible and available in the **Elements** panel.

![Currency exchange page block](bundle_page_block.png)
juskora marked this conversation as resolved.
Show resolved Hide resolved
Loading