diff --git a/content/en/docs/appstore/_index.md b/content/en/docs/appstore/_index.md
index 010a3570fd9..aa86380c296 100644
--- a/content/en/docs/appstore/_index.md
+++ b/content/en/docs/appstore/_index.md
@@ -16,13 +16,18 @@ The Mendix Portal is the online platform of Mendix. It includes [Apps](/develope
## Introduction
-Mendix Studio Pro contains a lot of core out-of-the-box widgets such as data grids and snippets. If you want to extend your application with more widgets and modules (for example, the [Forgot Password module](https://marketplace.mendix.com/link/component/1296/)), simple charts, an [Excel importer](https://marketplace.mendix.com/link/component/1296/), and other features, and make your development move even more quickly, you can use content from the [Mendix Marketplace](https://marketplace.mendix.com/), as it is a robust platform for the rapid development of apps. The Marketplace contains many useful and reusable widgets and modules created by Mendix as well as by our partners and community.
+Mendix Studio Pro includes many core out-of-the-box widgets, such as data grids and snippets. You can, however, extend your application with more features, widgets, and modules, such as the [Forgot Password module](https://marketplace.mendix.com/link/component/1296/)), simple charts, an [Excel importer](https://marketplace.mendix.com/link/component/1296/), thus making your development even faster. You can do this by using content from the [Mendix Marketplace](https://marketplace.mendix.com/). The Mendix Marketplace is a robust platform for the rapid development of apps, which contains many useful and reusable widgets and modules created by Mendix, as well as by our partners and community. It includes complete sample apps that can be used right away, as well as various components, such as connectors, modules, and widgets, that can be used to build your apps more quickly. In the Mendix Marketplace, you can browse all the content, get what you need, and share the content you have created.
-This documentation of **Marketplace** presents documentation on configuring and using the latest versions of [platform-supported](/appstore/marketplace-content-support/#category) Marketplace components.
+This document provides the following:
- In addition to downloading content from the Marketplace, you can upload components you have developed to share and help the whole Mendix community. The documentation also contains guidelines on [creating Marketplace content](/appstore/creating-content/) to share and sell.
+* Details on configuring and using the latest versions of [platform-supported](/appstore/marketplace-content-support/#category) Marketplace components
+* Guidelines on [creating Marketplace content](/appstore/creating-content/) to share and sell
-For details on the Studio Pro version required for use and when the component was published, please see the specific component page in the Mendix Marketplace. For more information, see the [Marketplace release notes](/releasenotes/marketplace/).
+Mendix Studio Pro includes many core out-of-the-box widgets, such as data grids and snippets. You can, however, extend your application with more features, widgets, and modules, such as the [Forgot Password module](https://marketplace.mendix.com/link/component/1296/)), simple charts, an [Excel importer](https://marketplace.mendix.com/link/component/1296/).
+
+For details on the Studio Pro version required for use and when the component was published, please see the specific component page in the Mendix Marketplace.
+
+To stay up to date with changes, see the [Marketplace release notes](/releasenotes/marketplace/).
## Types of Marketplace Components {#components-type}
@@ -32,11 +37,11 @@ The Marketplace offers the following content types:
| --------------------------------- | ------------------------------------------------------------ |
| [Module](/appstore/modules/) | Software functionality that can include a data model, logic, and UI with a portable security model. |
| [Widget](/appstore/widgets/) | Single user-interface elements like containers, drop-down menus, and buttons. Select a widget, configure it, and add it to pages and snippets in your app. |
-| **Service** | Software functionality that can be re-used for different use cases. Services usually include APIs that you can interact with by configuring a connection in the app’s module. |
-| **Solution** | Out-of-the-box solutions that are aimed at industry and domain problems, delivering instant value. These solutions are usually at least 80% ready for use and need minimal adaptation to make them work for a customer-specific use case. |
+| [Service](/appstore/services/) | Software functionality that can be re-used for different use cases. Services usually include APIs that you can interact with by configuring a connection in the app’s module. |
+| [Solution](/appstore/creating-content/sol-solutions-guide/) | Out-of-the-box solutions that are aimed at industry and domain problems, delivering instant value. These solutions are usually at least 80% ready for use, and need minimal adaptation to make them work for a customer-specific use case. |
| **Sample** | A project that provides an overview of the capabilities a product can perform. The project can act as an example, sales play, demo, or template. |
| **Starter Template** | Sample projects that have certain capabilities in place to provide a basis for you to start developing your own app. You do not need to create an app from a blank template, as you can use a template that already has some features configured. In addition, a template can have a personalized style that can be shared and used to enrich other apps with a specific design. |
-| **Industry Template** | Accelerators for implementing industry-specific processes. Industry templates increase speed-to-value and time-to-market, and they are great starting points for common use cases within the relevant industry. Contrary to solutions, industry templates are starter templates intended to provide inspiration for utilizing Mendix to create apps for industry-specific processes. They usually cover around 20% of the process. |
+| **Industry Template** | Accelerators for implementing industry-specific processes. Industry templates increase speed-to-value and time-to-market, and are great starting points for common use cases within the relevant industry. Contrary to solutions, industry templates are starter templates intended to provide inspiration for utilizing Mendix to create apps for industry-specific processes. They usually cover around 20% of the process. |
## Marketplace and Mendix Connect {#marketplace-mx-connect}
@@ -49,7 +54,7 @@ The Marketplace offers the following content types:
* [MQTT](/appstore/modules/mqtt/) connector
* [Mendix Business Events](/appstore/services/business-events/) module
-And our strategic partner connectors:
+These are our strategic partner connectors:
* [AWS connectors](/appstore/aws-modules/)
* [SAP connectors](/partners/sap/)
diff --git a/content/en/docs/appstore/create-content/_index.md b/content/en/docs/appstore/create-content/_index.md
index d95b7d8c362..cf81cfb061c 100644
--- a/content/en/docs/appstore/create-content/_index.md
+++ b/content/en/docs/appstore/create-content/_index.md
@@ -1,5 +1,5 @@
---
-title: "Create Marketplace Content"
+title: "Creating Marketplace Content"
url: /appstore/creating-content/
description: "Present details on creating content for the Mendix Marketplace."
weight: 2
diff --git a/content/en/docs/appstore/create-content/create-connectors/_index.md b/content/en/docs/appstore/create-content/create-connectors/_index.md
index 1d5bdb45ca7..7118f20b03b 100644
--- a/content/en/docs/appstore/create-content/create-connectors/_index.md
+++ b/content/en/docs/appstore/create-content/create-connectors/_index.md
@@ -1,5 +1,5 @@
---
-title: "Create Connectors"
+title: "Creating Connectors"
url: /appstore/creating-content/connector-guide-build/
weight: 4
description: "Introduces the concept of connectors, how they work, and the basic steps for building and publishing connectors."
@@ -7,7 +7,7 @@ description: "Introduces the concept of connectors, how they work, and the basic
## Introduction
-Welcome to the world of Mendix connectors. Mendix connectors allow you to connect your Mendix application to other systems. You can find them on the [Mendix Marketplace](https://marketplace.mendix.com/), or add them to the Marketplace for others to use.
+Mendix connectors allow you to connect your Mendix application to other systems. You can find them on the [Mendix Marketplace](https://marketplace.mendix.com/), or add them to the Marketplace for others to use.
This how-to teaches you the following:
@@ -22,40 +22,40 @@ For in-depth instructions and best practices, see [Best Practices for Building C
Before starting this how-to, make sure you have completed the following prerequisites:
-* Read the blog post [Introducing the Mendix Connector Kit](https://www.mendix.com/blog/introducing-mendix-connector-kit/)
-* Read [How to Share Marketplace Content](/appstore/submit-content/)
-* Read the Evaluation Guide page about [Integration](https://www.mendix.com/evaluation-guide/app-capabilities/integration/)
-* Read [How to Build Microflow Actions with Java](/howto/extensibility/howto-connector-kit/)
-* Watch the [Build a Mendix Connector](https://www.youtube.com/watch?v=wTQJ1MiXAow) tutorial
-* Install Studio Pro
+* Read the [Introducing the Mendix Connector Kit](https://www.mendix.com/blog/introducing-mendix-connector-kit/) blog post.
+* Read [How to Share Marketplace Content](/appstore/submit-content/).
+* Read the Evaluation Guide page about [Integration](https://www.mendix.com/evaluation-guide/app-capabilities/integration/).
+* Read [How to Build Microflow Actions with Java](/howto/extensibility/howto-connector-kit/).
+* Watch the [Build a Mendix Connector](https://www.youtube.com/watch?v=wTQJ1MiXAow) tutorial.
+* Install Studio Pro.
-## What Are Connectors?
+## Connectors Defined
Connectors can be used in your app to simplify connecting to existing third-party systems or other Mendix applications.
### Connecting to Other Systems
-Connectors are implemented as Mendix modules with a focus on connecting to other systems. Connectors can make use of any of the platform-supported protocols like [SOAP](/refguide/consumed-web-services/#soap), [REST](/refguide/integration/rest-services/), [OData](/refguide/consumed-odata-services/#external-entities), or [Catalog](/catalog/).
+Connectors are implemented as Mendix modules focused on connecting to other systems. They can use any of the platform-supported protocols like [SOAP](/refguide/consumed-web-services/#soap), [REST](/refguide/integration/rest-services/), [OData](/refguide/consumed-odata-services/#external-entities), or [Catalog](/catalog/).
-They can also be used to package a Java library provided by the other system to make the connection. These Java library functions can be exposed via Java actions as custom microflow activities (see [How to Build Microflow Actions with Java](/howto/extensibility/howto-connector-kit/)). This makes it simpler for Mendix developers without in-depth knowledge about third-party integrations to use these connectors in their business logic.
+Connectors can also be used to package a Java library provided by the other system to make the connection. These Java library functions can be exposed via Java actions as [custom microflow activities](/howto/extensibility/howto-connector-kit/). This makes it simpler for Mendix developers without in-depth knowledge about third-party integrations to use these connectors in their business logic.
#### Connecting Mendix Apps to Mendix Apps
-This chart shows the available solutions for when you want to connect Mendix apps to other Mendix apps:
+This table shows the solutions you can use when you want to connect Mendix apps to other Mendix apps:
| Category | Solution |
| --- | --- |
-| Platform-supported protocols | Connect to two or more Mendix applications using platform-supported facilities:
SOAP web services (see [Published Web Services](/refguide/published-web-services/) and [Consumed Web Services](/refguide/consumed-web-services/)), REST web services (see [Published REST Services](/refguide/published-rest-service/) and [Consumed REST Service](/refguide/consumed-rest-service/)), OData (see [Published OData Services](/refguide/published-odata-services/) and [Consumed OData Services](/refguide/consumed-odata-services/)), or Catalog (see the [Catalog Guide](/catalog/)). |
-| Unsupported protocols | Build a module to connect either with alternative protocols or by encapsulating one of the platform supported protocols. You can do this with [Java actions](/refguide/java-actions/) or [JavaScript actions](/refguide/javascript-actions/). |
+| Platform-supported protocols | Connect to two or more Mendix applications using platform-supported facilities:
- SOAP web services (see [Published Web Services](/refguide/published-web-services/) and [Consumed Web Services](/refguide/consumed-web-services/))
- REST web services (see [Published REST Services](/refguide/published-rest-service/) and [Consumed REST Service](/refguide/consumed-rest-service/))
- OData (see [Published OData Services](/refguide/published-odata-services/) and [Consumed OData Services](/refguide/consumed-odata-services/))
- Catalog (see the [Catalog Guide](/catalog/))
|
+| Unsupported protocols | Build a module to connect either with alternative protocols, or by encapsulating one of the platform supported protocols. You can do this with [Java actions](/refguide/java-actions/) or [JavaScript actions](/refguide/javascript-actions/). |
#### Connecting Mendix Apps to Third-Party Systems
-This chart shows the available solutions for when you want to connect Mendix apps to third-party systems:
+This table shows the solutions you can use when you want to connect Mendix apps to third-party systems:
| Category | Solution |
| --- | --- |
-| Platform-supported protocols | Connect a Mendix application to one or more third party applications using platform-supported facilities: SOAP web services, REST web services or OData. |
-| eQube-supported protocols | Use eQube-supported facilities: Web services, REST, OData |
+| Platform-supported protocols | Connect a Mendix application to one or more third party applications using platform-supported facilities: - SOAP web services
- REST web services
- OData
|
+| eQube-supported protocols | Use eQube-supported facilities: |
| Unsupported protocols | Build a module to connect either via alternative protocols, or by encapsulating one of the platform supported protocols. |
{{% alert color="info" %}}
@@ -64,26 +64,26 @@ The [Catalog](/catalog/) is a hub for shared registered assets made available in
### Getting Mendix Connectors
-Many existing Mendix Connectors can be downloaded from the [Mendix Marketplace](https://marketplace.mendix.com/) directly into your app. Depending on your use case, your company's private Mendix Marketplace could also have a variety of Mendix connector modules available. For more information on the distinction between public and private Marketplace content, see the [Adding New Marketplace Content](/appstore/submit-content/#adding) section of *Share Marketplace Content*.
+Many existing Mendix Connectors can be downloaded from the [Mendix Marketplace](https://marketplace.mendix.com/) directly into your app. Depending on your use case, your company's private Mendix Marketplace could also have a variety of Mendix connector modules available. For more information on the distinction between public and private Marketplace content, see the [Adding New Marketplace Content](/appstore/submit-content/#adding) section of *Uploading to the Marketplace*.
-Because connectors expose data via custom microflow activities, you can find them in the Studio Pro [Toolbox](/refguide/view-menu/#toolbox) to implement when building your application logic. Then, you can drag them to where you want to use the connector functionality.
+Connectors expose data via custom microflow activities. As such, you can find them in the Studio Pro [Toolbox](/refguide/view-menu/#toolbox) to implement when building your application logic. Then, you can drag them to where you want to use the connector functionality.
### Deploying Connectors
-Once you deploy an application, the connector will automatically deploy with it. You can also set a few runtime or node specific configurations (via the application interface or constants).
+Once you deploy an application, the connector automatically deploys with it. You can also set a few runtime or node specific configurations (via the application interface or constants).
-As an example, check out the [Amazon SNS](/appstore/modules/aws/amazon-sqs/) connector. This connector uses AWS-provided libraries to interact with the Amazon Simple Notification Service. The functions are exposed via a set of Mendix actions that are available in the toolbox to use in your logic.
+As an example, check out the [Amazon SNS](/appstore/modules/aws/amazon-sqs/) connector. This uses AWS-provided libraries to interact with the Amazon Simple Notification Service. The functions are exposed via a set of Mendix actions that are available in the toolbox to use in your logic.
## Building a Mendix Connector in Studio Pro {#build-connector}
-When creating a new Mendix connector, it is advised to have an app in which you both develop and test your connector. This means that you will have a module that contains all your connector logic, along with one or more additional modules that assist in the testing and development. The logic in the additional modules are not required for the operation of the module and therefore need to be separated.
+When creating a new Mendix connector, it is advised to have an app in which you both develop and test your connector. This means that you will have a module that contains all your connector logic, along with one or more additional modules that assist in the testing and development. The logic in the additional modules is not required for the main module to operate, and therefore needs to be separated.
### Setting Up Your App {#app-setup}
To start setting up your app, open Studio Pro and do the following:
-1. Create a [New App](/refguide/new-app/) for your connector.
-2. Create a module to contain your connector. To do this, right-click anywhere in the **App Explorer** outside of existing modules and choose **Add Module**.
+1. Create a [new app](/refguide/new-app/) for your connector.
+2. Create a module to contain your connector. To do this, right-click anywhere in the **App Explorer** outside of existing modules, and choose **Add Module**.
{{< figure src="/attachments/appstore/create-content/create-connectors/add-module.png" class="no-border" >}}
@@ -94,18 +94,19 @@ For more information, see the [App Setup](/appstore/creating-content/connector-g
### Implementing the Connector {#implement}
-How you implement the module is entirely up to you and your use case, but it is good to keep the following in mind:
+How you implement the connector is entirely up to you and your use case, but it is good to keep the following in mind:
* Document the parts that are to be used by the implementing application.
* Provide a granular security model that allows the implementing application to use your connector in a secure way.
-* Hide complex parts, preferably in the Java code, or at least in the private folder. Future Mendix versions will include an option to secure your IP in the Mendix module, but for now that is only possible using a Java library.
-* Minimize dependencies to easily available libraries/modules that are well maintained. And where possible do not use any dependencies.
-* Contain all your core code in your connector module. Anything assisting you during development or testing should be in separate modules using the connector module but never the other way around.
+* Hide complex parts, preferably in the Java code, or at least in the private folder.
+* Apply Intellectual Property (IP) protection to your Mendix module. For more information, refer to [Applying Intellectual Property Protection](/appstore/creating-content/sol-ip-protection/).
+* Minimize dependencies to easily available libraries/modules that are well maintained. Where possible, do not use any dependencies.
+* Contain all your core code in your connector module. Anything assisting you during development or testing should be in separate modules using the connector module, but never the other way around.
* Test your connector.
### Exporting the Connector {#export}
-Because Mendix connectors are like any other Mendix [module](/appstore/modules/), you can export them from your app. When a connector module is exported, the following will also export:
+Mendix connectors are like any other Mendix [module](/appstore/modules/), which means you can export them from your app. When a connector module is exported, the following are also exported:
* Entities
* Microflows
@@ -120,30 +121,31 @@ Because Mendix connectors are like any other Mendix [module](/appstore/modules/)
To export your connector as an *.mpk* file, do the following:
-1. Ensure your version is aligned with the version number that appears on the Marketplace version. Versioning in Marketplace starts at 1.0.0 (for more information, see the [Adding New Marketplace Content](/appstore/submit-content/#adding) section in *How to Share Marketplace Content*). You cannot use Marketplace to distribute your connector if it is below version 1.0.0.
+1. Ensure your version is aligned with the version number that appears on the Marketplace. Versioning in Marketplace starts at 1.0.0 (for more information, see the [Adding New Marketplace Content](/appstore/submit-content/#adding) section in *Uploading to the Marketplace*). You cannot use Marketplace to distribute your connector if it is below version 1.0.0.
2. Generate the export module package using your [Gradle script](https://github.com/ako/CsvServices/blob/cd219e71249c194bca26b374716b88628237a6dd/build.gradle#L72).
-3. Build and export release candidate with versioning and put it in the Marketplace **DIST** folder. You can create this folder to contain the releases of your module for reference.
+3. Build and export a release candidate with versioning and put it in the Marketplace **DIST** folder. You can create this folder to contain the releases of your module for reference.
### Distributing the Connector {#distribute}
-To share your connector with other developers and the wider community, you can publish it in the Mendix Marketplace. While publishing, you may choose to publish it for everyone or just for your company. In case you choose the second option, it will only be available to other developers belonging to the same company. For more information on how to publish to the Marketplace, and the difference between public and private publishing, see the [Adding New Marketplace Content](/appstore/submit-content/#adding) section of *Share Marketplace Content*.
+To share your connector with other developers and the wider community, you can publish it in the Mendix Marketplace. You can choose to publish it for everyone or just for your company. If you choose to only publish for your company, it will only be available to other developers belonging to the same company as you. For more information on how to publish to the Marketplace, and the difference between public and private publishing, see the [Adding New Marketplace Content](/appstore/submit-content/#adding) section of *Uploading to the Marketplace*.
Once you publish the connector and someone imports it in their Mendix app, all of these elements will be placed in the same location from which they are exported.
-Distribute the module to whomever wants to use it (share the file or upload to Marketplace) by following these steps:
+You can distribute the module to those who want to use it, by either sharing the file or uploading it to the Marketplace. Follow these steps to do so:
1. Keep the release notes ready.
2. Deploy to GitHub by doing the following:
- * Commit code to GitHub (if you have not already made this a Git project)
- * Create new release
+
+ 1. Commit the code to GitHub (if you have not already made this a Git project).
+ 2. Create a new release.
3. Create the release in Marketplace using the release from GitHub.
### Architectural Impact
-Because connectors are exported as modules and then published on the Marketplace, they are as decoupled as possible from your development application. This is needed because a copy of the module will be imported in other applications when users download the module from the Marketplace. The implementing application might need to configure some constants, add specific microflows, use pages or snippets, configure specifics on runtime, but it will always be a standalone situation.
+Connectors are exported as modules, and then published to the Marketplace. For this reason, they are as decoupled as possible from your development application. This is needed because a copy of the module will be imported in other applications when users download the module from the Marketplace. The implementing application might need to configure some constants, add specific microflows, use pages or snippets, configure specifics on runtime, but it will always be a standalone situation.
## Read More
-* Read [How to Share Marketplace Content](/appstore/submit-content/)
-* Check out [Best Practices for Building Connectors](/appstore/creating-content/connector-guide-best-practices/)
+* [Uploading to the Marketplace](/appstore/submit-content/)
+* [Best Practices for Building Connectors](/appstore/creating-content/connector-guide-best-practices/)
* See more about building a third-party service connector using [OData Services](/refguide/integration/odata-services/)
diff --git a/content/en/docs/appstore/create-content/create-connectors/connector-guide-best-practices.md b/content/en/docs/appstore/create-content/create-connectors/connector-guide-best-practices.md
index 0f083556b1e..a8234941c02 100644
--- a/content/en/docs/appstore/create-content/create-connectors/connector-guide-best-practices.md
+++ b/content/en/docs/appstore/create-content/create-connectors/connector-guide-best-practices.md
@@ -6,51 +6,51 @@ weight: 7
## Introduction
-In [Build Connectors](/appstore/creating-content/connector-guide-build/), you learned about the background and basic steps of building connectors. This guide will go into more detail and explore recommended practices for building, testing, and distributing connectors.
+This document provides details and recommended best practices for building, testing, and distributing connectors.
## App Setup {#app-setup}
-This section dives into best practices for setting up your app in Studio Pro. For the basic instructions, see the [Setting Up Your App](/appstore/creating-content/connector-guide-build/#app-setup) section of *Build Connectors*.
+This section dives into best practices for setting up your app in Studio Pro. For basic instructions, see the [Setting Up Your App](/appstore/creating-content/connector-guide-build/#app-setup) section of *Creating Connectors*.
### Studio Pro Version
-For people to use your connector, ensure that you are not only servicing toward end-users that have the latest version. Try to support the latest [LTS](/releasenotes/studio-pro/lts-mts/) version, or if possible even older supported versions.
+For people to use your connector, ensure that you are not only targeting end-users that have the latest version Studio Pro. Try to support the latest [LTS](/releasenotes/studio-pro/lts-mts/) version and, if possible, even older supported versions.
The only reason to deviate from this is when your connector requires a certain platform functionality that is only available in a newer version, or requires another module that is only available on a newer version. In that case, use that newer version as your Mendix required version.
### Modules in the App
-Create a Mendix app in Studio Pro with the main connector module and a testing module. You can also optionally add an example module showing some use cases.
+Create a Mendix app in Studio Pro with the main connector module and a testing module. You can also add an example module showing some use cases.
-* Name the *main module* how you want it to appear in apps after others import your module. This module will contain all the logic to let your connector function in apps that import it.
-* The *testing module* has microflows, pages, and Java code to test your module's functionality without having to add the test logic to the module that you will later export and publish.
-* The *example module* can be published next to the main connector module to help end-users better understand the implementation of your connector module, or to try it out without having to do too much configuration from the start.
+* The main module contains all the logic needed to let your connector function in apps that import it. Give the main module the name you want to appear in apps after others import your module.
+* The testing module has microflows, pages, and Java code to test your module's functionality. This means that you will not have to add the test logic to the module that you will later export and publish.
+* You can publish the example module next to the connector main module and testing module to help end-users better understand the implementation of your connector module, or to try it out without having to do too much configuration from the start.
-#### Main Connector Module Setup {#main-setup}
+#### Setting Up the Main Connector Module {#main-setup}
-Mendix recommends the *main module* for your connector include the following:
+Mendix recommends that the main module for your connector include the following:
-* **_Docs** (folder) – contains documentation or a reference to documentation and a version indicator
- * **ReadMe** (snippet) – used to give a reference to documentation and/or some direct documentation on how to use the module
- * **[ModuleName]_Version** (string constant) – replace the [ModuleName] part with your module name and fill the value with the version of the module using the same standard as the Mendix Marketplace 1.2.3 (see the [Versioning](#versioning) section below)
- * As an alternative to the version constant, you can place a subfolder with the version indication
-* **Private** (folder)– indicates what other developers should not touch when implementing your module by placing all of that logic in this folder
-* **UseMe** (folder) – contains everything the implementing developer could use to implement your module in their application, and might include subfolders for **Microflows**, **Pages**, **Snippets**, **Templates**, and **Constants**
+* **_Docs** (folder) – Contains documentation or a reference to documentation, and a version indicator.
+ * **ReadMe** (snippet) – Used to give a reference to documentation and/or some direct documentation on how to use the module.
+ * **[ModuleName]_[Version]** (string constant) – Replace [ModuleName] with the name of your module, and [Version] with the version of the module. Use the same standard as the Mendix Marketplace 1.2.3. See the [Versioning](#versioning) section below.
+ * As an alternative to the version constant, you can include a subfolder with the version indication.
+* **Private** (folder) – This folder contains all the logic that other developers should not touch when implementing your module.
+* **UseMe** (folder) – Contains everything the implementing developer could use to implement your module in their application. It can include subfolders for **Microflows**, **Pages**, **Snippets**, **Templates**, and **Constants**.
-Your **App Explorer** should look like this after initial setup:
+Your **App Explorer** should look like this after the initial setup:
{{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/app-initial-setup.png" class="no-border" >}}
{{% alert color="info" %}}
-This app folder structure example is based on the **Blank Web App** starter app and contains Mendix Marketplace modules that your app might not have. The important Marketplace module that is shown is the [Unit Testing](/appstore/modules/unit-testing/) module for testing purposes.
+This app folder structure example is based on the **Blank Web App** starter app, and contains Mendix Marketplace modules that your app might not have. The important Marketplace module that is shown is the [Unit Testing](/appstore/modules/unit-testing/) module for testing purposes.
{{% /alert %}}
-#### App Root Setup {#root-setup}
+#### Setting Up the App Root {#root-setup}
-Mendix recommends adding add additional folders to the root of your app (on disk). These include the following:
+Mendix recommends adding additional folders to the root of your app, on disk. These include the following:
-* **DIST** – contains the releases of your module kept for reference
-* **MarketplaceResources** – contains all the assets used in the Mendix Marketplace (except for the release packages), including screenshots, videos, and reference documents
+* **DIST** – This contains the releases of your module kept for reference.
+* **MarketplaceResources** – This contains all the assets used in the Mendix Marketplace, such as screenshots, videos, and reference documents. It does not contain the release packages.
The app root of your **App Explorer** should look like this after root setup:
@@ -58,55 +58,53 @@ The app root of your **App Explorer** should look like this after root setup:
#### Importing Dependency Modules
-Use as few dependency modules as possible. When you must use one, make sure they are either maintained by your own company (when creating a company-only connector) and/or platform-supported so users are not left unsupported. Otherwise, you might end up having to maintain those public non-platform supported modules to ensure that your connector operates properly.
+Use as few dependency modules as possible. When you must use one, make sure it is either platform supported or, if you are creating a company-only connector, maintained by your own company. This ensure that users are are always supported. Otherwise, you might end up having to maintain those public non-platform supported modules to ensure that your connector operates properly.
### Adding the App to Version Control
-Add the app to [Team Server](/refguide/version-control/#team-server) (or GitHub) version control, if you have not already done so when creating the app.
-
-Mendix recommends having a separate public Git repository next to your private Team Server Git repository, so that you can continue committing and applying changes while you only push to the public repository for a new release to the Marketplace. The automated integration with GitHub from the Marketplace makes this a good option for your public-facing Git repository.
+If you have not already added your app, add it to the [Team Server](/refguide/version-control/#team-server). An alternative solution that Mendix recommends is having a separate public Git repository next to your private Team Server Git repository. This way, you can continue committing and applying changes while you only push to the public repository for a new release to the Marketplace. The automated integration with GitHub from the Marketplace makes this a good option for your public-facing Git repository.
### Working with Java-Intensive Apps
-For Java-intensive apps, consider creating an **Implementation** sub-module to keep core implementation separate. You can also make the module a Gradle project in order to better manage dependencies and release pipeline. Create the *gradle.build* file to manage Java library dependencies and cleanup of the **userlib** folder for export. For further information, see [Extend App Setup for Building Connectors with Java](#extend-app-java) below.
+For Java-intensive apps, consider creating an **Implementation** submodule to keep core implementation separate. You can also make the module a Gradle project in order to better manage dependencies and the release pipeline. Create the *gradle.build* file to manage Java library dependencies and the cleanup of the **userlib** folder for export. For further information, see [Extending App Setup for Building Connectors with Java](#extend-app-java) below.
## Development
-This section explores best practices for connector development. You can develop connectors using Java or using Mendix.
+This section explores best practices for connector development. You can develop connectors using Java or Mendix.
### Developing Connectors Using Java
Implementing the bulk of the functionality in Java has the following benefits:
-* Complexity is hidden from end-users and apps are easier to understand.
+* Complexity is hidden from end-users, making apps easier to understand.
{{% alert color="info" %}}
-Mendix apps should focus on solving the business requirements. Generic technical constructs should be hidden from the developers. Currently, Java is the best way to achieve this. A module does not have to ship the Java source for its Java functionality. You can also make a (hidden) *.jar* in another app, and place that in the connector module **user lib**.
+Mendix apps should focus on solving business requirements. Generic technical constructs should be hidden from developers. Currently, Java is the best way to achieve this. A module does not have to ship the Java source for its Java functionality. You can also make a (hidden) *.jar* in another app, and place that in the connector module **user lib**.
{{% /alert %}}
* End-users are less likely to change it.
* You can use [unit tests](#unit-testing).
#### Extending App Setup for Building Connectors with Java {#extend-app-java}
-You can extend your app to work with Java and Gradle.
+You can extend your app to work with Java and Gradle. Follow these steps to do that:
1. Add an **Implementation** folder next to other app folders.
{{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/implementation-folder.png" class="no-border" >}}
-2. Set up an **Implementation** folder as a Gradle `java-library` project. For details, see Gradle documentation on [Building Java Libraries Sample](https://docs.gradle.org/current/samples/sample_building_java_libraries.html#run_the_init_task). This is the expansion of the **Implementation** folder:
+2. Set up an **Implementation** folder as a Gradle `java-library` project. For details, see the Gradle documentation on [Building Java Libraries Sample](https://docs.gradle.org/current/samples/sample_building_java_libraries.html#run_the_init_task). This is the expansion of the **Implementation** folder:
{{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/gradle-library.png" class="no-border" >}}
- The **Implementation** folder is now a self contained Gradle project which can be opened in any IDE which understands Gradle and expanded with any code you like.
+ The **Implementation** folder is now a self contained Gradle project. It can be opened in any IDE that understands Gradle, and expanded with any code you like.
-3. Build the **Implementation** folder and place the resulting *.jar* to the **userlib** folder.
+3. Build the **Implementation** folder and place the resulting *.jar* in the **userlib** folder.
If your implementation has additional dependencies, consider creating one `fat jar` containing all dependent *.jar* files.
{{% alert color="info" %}}
All modules have their *.jar* files in the **userlib** folder. In order to specify that this *.jar* is being used by your connector module, add an additional text file named `-.requiredLib` .
{{% /alert %}}
-4. After implementation libraries are placed into the **userlib** folder, they are available in the Mendix application classpath so they can be used in a Java action in your connector module.
+4. After implementation, libraries are placed in the **userlib** folder, and are available in the Mendix application classpath so they can be used in a Java action in your connector module.
You can also extend your app with Gradle and add the **Implementation** project as a sub-module. In this case, your implementation project becomes part of your Mendix app. You can use it in Java actions without having to copy the *.jar* files to the **userlib** folder.
@@ -114,89 +112,96 @@ You can also extend your app with Gradle and add the **Implementation** project
You must have the *.jar* file placed in the **userlib** folder before exporting the connector module. Otherwise, **Implementation** *.jar* files will not be packaged with the module.
{{% /alert %}}
-A self-contained Gradle project can do unit testing and integration testing in the same way as you would do in any other Java project. See the [Testing](#testing) section of this document for best testing practices.
+A self-contained Gradle project can do unit testing and integration testing in the same way as you would do in any other Java project. See the [Testing](#testing) section of this document for best practices.
### Developing Connectors with Mendix
-While Java is likely going to be a primary choice for building your connector modules, it is not your only option. Lucky you!
+While Java is likely going to be a primary choice for building your connector modules, you can also use Mendix.
#### Making Microflows Available as Microflow or Workflow Activities
-To ensure that end-users can reuse your Mendix build logic as easily as possible, you will need to make microflows available as microflow or workflow activities (see the [Triggering a Workflow via a Microflow](/refguide/perform-workflow-basic-functions/#trigger-microflow) section of *Performing Workflow Basic Functions*).
+To ensure that end-users can reuse your Mendix build logic as easily as possible, you need to make microflows available as microflow or workflow activities. For details, see the [Triggering a Workflow via a Microflow](/refguide/perform-workflow-basic-functions/#trigger-microflow) section of *Performing Workflow Basic Functions*).
-Ensure that a microflow is visible in the **Toolbox** in the [Expose as microflow action](/refguide/java-actions/#expose-microflow-action) section of the microflow properties. You can do this by right-clicking in your microflow working area. Additionally, you can specify a caption for the action, a category for the **Toolbox**, and an icon. These will be used in the **Toolbox**, and also in the microflows, so these will be easy to read for the end-user:
+Ensure that a microflow is visible in the **Toolbox**, in the [Expose as microflow action](/refguide/java-actions/#expose-microflow-action) section of the microflow properties. You can do this by right-clicking in your microflow working area. Additionally, you can specify a caption for the action, a category for the **Toolbox**, and an icon. These will be used in the **Toolbox**, and also in the microflows, so they need to be easy to read for the end-user:
{{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/microflow-action.png" class="no-border" >}}
After you [expose as microflow action](/refguide/java-actions/#expose-microflow-action), this can be dragged and dropped inside another microflow.
-If you create functionality that requires for example REST API integrations or complex data processing, make sure you have well-documented microflows connecting your *public* part of the module to the *private* part. By doing this, you can shield the implementing developer from having to understand the REST API integration or complex data processing logic.
+If you create functionality that requires REST API integrations or complex data processing, make sure you have well-documented microflows connecting the public part of your module to the private part. This way, the implementing developer will not have to understand the intricacies of the integration.
-#### Naming and Choice of Icon
+If you create functionality that requires REST API integrations or complex data processing, make sure you have well-documented microflows connecting the public part of your module to the private part. This way, the implementing developer will not have to understand the intricacies of the integration.
-Make sure the name of your category matches the name of the category for similar functionality, and that the name of the caption for your microflow or workflow exposed action does not overlap with others.
+Follow these guidelines for names and icons:
-The icon should give instant recognition to your function. Make sure that it square and 16 by 16 pixels. This is very small, so try not to overdo it on the details.
+* The name of your category must match the name of the category which covers similar functionality.
+* The name of the caption for your microflow or workflow exposed action does not overlap with others.
+* The icon should give instant recognition to your function. Make sure that it is square and 16 by 16 pixels. This size is very small, so try not to add too many details.
#### Structuring the Usage of Your Connector
-As stated in the [Main Connector Module Setup](#main-setup) section, each connector build will have a **UseMe** folder where you expose the logic that users of your connector module need when implementing your module. You have the ability to expose your microflows and Java actions in the toolbox. This means that users will be able to use your microflows and Java actions as microflow activities or workflow system tasks. You can also add page templates that are reusable.
+As stated in the [Setting Up the Main Connector Module](#main-setup) section, each connector build will have a **UseMe** folder where you expose the logic that users of your connector module need when implementing your module. You can expose your microflows and Java actions in the toolbox. This means that users will be able to use your microflows and Java actions as microflow activities or workflow system tasks. You can also add page templates that are reusable.
-When exposing your microflows and Java actions, you need to ensure that end-users will be able to find them easily. As an example, take a look at how the category, icon, and name are listed for platform-supported items. Add documentation to your input parameters and for the full Java action/Microflow. This is part of the platform end-users will be able to access easily while using your Java action/microflow activities.
+When exposing your microflows and Java actions, you need to ensure that end users can find them easily. As an example, take a look at how the category, icon, and name are listed for platform-supported items. Add documentation to your input parameters and for the full Java action/microflow. This is part of the platform end users will be able to access easily while using your Java action/microflow activities.
For page templates, make sure to use a representative image, define a category that makes sense based on your module usage, and give a name that makes the template easily recognizable.
### Logging
-When something goes wrong or the module needs to expose information that it is unable to expose via the regular outputs, logging is a good option. Make sure your connector uses one log node for all the log messages if they are logged from the Java code or the Mendix code.
+When something goes wrong or the module needs to expose information that it is unable to expose via regular outputs, logging is a good option.
+
+Make sure your connector uses one log node for all log messages if they are logged from the Java code or the Mendix code.
-Do make sure that you utilize the right log levels:
+Ensure you utilize the right log levels:
-* `CRITICAL` – when the thing that goes wrong harms the stability of the application
-* `ERROR` – when an error occurs that the process the end-user is executing via your connector cannot recover from
-* `WARNING` – when something went wrong, but the process can finish anyway
-* `INFO` – useful information that should always appear in log files
-* `DEBUG` – when the user needs to determine why the connector is not working as expected
-* `TRACE` – used to determine why the implementation is not working as expected
+* `CRITICAL` – The error harms the stability of the application.
+* `ERROR` – The process cannot recover from the error.
+* `WARNING` – Something went wrong, but the process can finish anyway.
+* `INFO` – Useful information that should always appear in log files.
+* `DEBUG` – The user needs to determine why the connector is not working as expected.
+* `TRACE` – Determine why the implementation is not working as expected.
### Data Storage
-Depending on your module's functionality, you might need to store data in the end-user's application. The downside is that end-users might delete your module to resolve issues such as **userlib** conflicts. We advise limiting the amount of data stored in persistable entities and passing the data via your exposed logic to the end-user's application logic instead. Then, the user may decide to store it or only use it during a process.
+Depending on your module's functionality, you might need to store data in the end user's application. The downside is that end users might delete your module to resolve issues such as **userlib** conflicts.
+
+We advise limiting the amount of data stored in persistable entities, and passing the data via your exposed logic to the end user's application logic instead. Then, they may decide to store it, or to only use it during a process.
### Task Queue
-Actions that may be batched or divided over multiple threads due to a large load or volume should be offloaded to the [task queue](/refguide/task-queue/). Using this method, you can offload multiple tasks at once to multiple instances and over multiple threads. You can also run these tasks in the background without the user request waiting for it. Make sure that the end-user is aware that something is going on by setting a certain Task Status, or maybe implementing a progress log.
+Actions that may be batched or divided over multiple threads due to a large load or volume should be offloaded to the [task queue](/refguide/task-queue/). Using this method, you can simultaneously offload multiple tasks to multiple instances, and over multiple threads. You can also run these tasks in the background without having to wait for a user request. Make sure that the end user is aware that something is going on by setting a certain Task Status, or by implementing a progress log.
If you are using Studio Pro [8.18](/releasenotes/studio-pro/8.18/) or older, you can consider using the process queue. See the [Replacing Process Queue](/refguide9/task-queue/#process-queue) section of *Task Queue* for the difference between these functionalities.
### ConnectionDetails Entity
-Use a **ConnectionDetails** entity for all general connection and security settings for the call. Use a **ConnectionDetails_Get** microflow in all your Operations. This way it is easy to change all the settings in one location. The individual settings can be stored in a constant or in the database and set in the create. Using constants are recommended because this avoids a dependency on the Encryption module.
+Use a **ConnectionDetails** entity for all general connection and security settings for the call. Use a **ConnectionDetails_Get** microflow in all your operations. This makes it easy to change all the settings in one location. Individual settings can be stored in a constant or in the database, and set during creation. Using constants is recommended because this avoids a dependency on the encryption module.
-{{% alert color="warning" %}} Using either the default value of a constant or the project’s configuration setting is unsafe. Both these places are readable by others and visible in the version management. If you can share these settings with other developers, set them in the project configuration and leave the default values blank. This will limit the risk of accidentally exposing the settings when exporting the module.{{% /alert %}}
+{{% alert color="warning" %}} Using either the default value of a constant, or the project’s configuration setting is unsafe. Both these places are readable by others and visible in the version management. If you can share these settings with other developers, set them in the project configuration and leave the default values blank. This will limit the risk of accidentally exposing the settings when exporting the module.{{% /alert %}}
-If you do need to store sensitive information in the database, then always use the [Encryption](/appstore/modules/encryption/) module to encrypt and store and to retrieve and decrypt the information.
+If you need to store sensitive information in the database, always use the [Encryption](/appstore/modules/encryption/) module to encrypt and store, and to retrieve and decrypt the information.
### Persistable Entities
-If possible, avoid storing persistable data into persistable entities for your connector module. Developers will remove modules when troubleshooting Java compile issues. If they add them back, data stored in persistable entities is lost.
+If possible, avoid storing persistable data in persistable entities for your connector module. Developers will remove modules when troubleshooting Java compiling issues. If they add them back, data stored in persistable entities is lost.
-It is better to use non-persistable entities and let the user decide how to store any data passed back from your connector in their own domain model.
+It is better to use non-persistable entities, and let the user decide how to store any data passed back from your connector in their own domain model.
### Toolbox Actions and Non-Persistable Entities (NPEs)
-Toolbox actions need clear naming, consistent categorization, and documentation, and NPEs should be well-organized visually.
+Toolbox actions need clear naming, consistent categorization, and documentation.
+
+NPEs should be well-organized visually.
### Attributes
Consider doing the following for all entity attributes:
* Set all string values to unlimited.
-* Check all date values. If the service only returns a date (no time), then set **localize** to *No*.
+* Check all date values. If the service only returns a date (no time), then set **localize** to **No**.
* Check all number values (decimal, integer, long), and remove the default value of 0.
{{% alert color="info" %}}
-
Databases like SAP HANA and Oracle do not support CLOBs for order by or group by clauses. Because of this, attributes that are used for sorting or group by operations should not be set to unlimited.
{{% /alert %}}
@@ -204,13 +209,13 @@ Databases like SAP HANA and Oracle do not support CLOBs for order by or group by
Given that there is no dependency management between Mendix modules, try to minimize the number of dependencies your module has on other modules. If you do have to depend on other modules, make sure those modules are well-maintained by you or by Mendix themselves. Introducing another community-supported module as a dependent module might be too much of a risk for developers wanting to use your module.
-Any dependencies your module has should be well documented including the minimum required version to be used. It is also recommended to use the *.RequiredLib* files that Mendix uses for platform-supported modules, best handled with a build script like Gradle. To learn more about working with Gradle, see [Extending App Setup for Building Connectors with Java](#extend-app-java).
+Any dependencies your module has should be well documented, including the minimum required version to be used. It is also recommended to use the *.RequiredLib* files that Mendix uses for platform-supported modules, best handled with a build script like Gradle. To learn more about working with Gradle, see [Extending App Setup for Building Connectors with Java](#extend-app-java).
### IP Protection
-For members of the [Mendix Partner Program](/appstore/partner-program/) and the [Mendix Commercial Solution Partner Program](https://www.mendix.com/partners/become-a-partner/isv-program/), protecting your intellectual property (IP) or preventing end-users from changing any logic that you ship in a module using Mendix tooling is possible. For details, see [How to Apply IP Protection](/appstore/creating-content/sol-ip-protection/).
+Members of the [Mendix Partner Program](/appstore/partner-program/) and of the [Mendix Commercial Solution Partner Program](https://www.mendix.com/partners/become-a-partner/isv-program/) can protect their intellectual property (IP) or prevent end users from changing any logic shipped in a module using Mendix tooling. For details, see [Applying Intellectual Property Protection](/appstore/creating-content/sol-ip-protection/).
-If protecting your IP or preventing end-users from changing your logic is not a requirement, you can use all the tooling that Mendix provides to build a connector using available Mendix tools. If you want IP protection today, you need to implement the sensitive parts of the module in a hidden Java library.
+If protecting your IP or preventing end users from changing your logic is not a requirement, you can build a connector using available Mendix tools. If you want IP protection today, you need to implement the sensitive parts of the module in a hidden Java library.
### Performance Considerations
@@ -224,7 +229,7 @@ When importing large datasets into Mendix application, use streamable formats to
If using NPEs, data retrieved by the connector is loaded into memory, so it is important to avoid requesting large amounts of data from an underlying system in a single call. Limiting or paginating the size of the retrieved data will lead to better performance for the Mendix app. Use server-side pagination for search results.
-To provide a proper user experience, the amount of data loaded and rendered on the page needs to be limited. A typical page size of 25 objects or 100 objects is recommend, with "load more" and filter/search options for optimized navigation through the dataset.
+To provide a proper user experience, the amount of data loaded and rendered on the page needs to be limited. A typical page size of 25 objects or 100 objects is recommend, with options to load more and filter or search for optimized navigation through the dataset.
#### Import Mappings (Deep Structures)
@@ -232,23 +237,23 @@ Mendix does not support import mappings for recursive structure. Consider simpli
#### Caching
-Use caching for frequently retrieved objects to reduce redundant database actions.
+Use caching to reduce redundant database action for frequently retrieved objects.
#### Domain Model
-A connector exposes the data of underlying system using its domain model. Consider the following during the domain model design so that app performs well:
+A connector exposes the data of the underlying system using its domain model. Consider the following during the domain model design to ensure proper app performance:
-* Do not expose the full data model complexity of the underlying source system in the connector domain model to facilitate easy data exchange. Try to only expose those pieces that are relevant for implementing your connector inside of the application of the implementing developer.
-* Keep connector logic (Java actions code, microflows) as light as possible. You need the ability to properly connect, but overcomplicating connector logic will be more difficult to implement.
-* Limit levels of inheritance and associations to not more than two, using persistable entities. In case of NPEs, this is not an issue, so consider using NPEs where possible.
-* Minimize the use of reference set (many-to-many) associations. Mendix retrieves the IDs (per row for a list retrieve) on every query. As a result, many references—and especially reference sets—cause extra queries and thus extra load on the database.
-* Consider adding indices where relevant. And make sure to add them in a way that they make sense with the querying logic in your connector and/or use cases for implementing apps.
-* Keep your persistable entities from growing too large. You may do this by adding a cleanup scheduled event scheduled event, which you should make configurable via constants (for example, for the batch size used to remove {x} amount of objects at a time).
-* Add a flexible but secure set of entity access rules based on the module roles that you add for access to the module. Keep in mind the use cases for your connector. If you are able to avoid any persistable data, that is recommended.
+* Do not expose the full data model complexity of the underlying source system in the connector domain model to facilitate easy data exchange. Try to only expose those pieces that are relevant for implementing your connector in the application of the implementing developer.
+* Keep connector logic, such as Java actions code and microflows, as light as possible. An overcomplicated connector logic is more difficult to implement.
+* Limit levels of inheritance and associations to no more than two, using persistable entities. This is not an issue for NPEs, so consider using them where possible.
+* Minimize the use of reference set (many-to-many) associations. Mendix retrieves the IDs (per row for a list retrieve) on every query. As a result, many references, and especially reference sets, cause extra queries, and thus extra load on the database.
+* Consider adding indices where relevant. Make sure to add them in a way that they make sense with the querying logic in your connector and/or use cases for implementing apps.
+* Keep your persistable entities from growing too large. You may do this by adding a scheduled cleanup event, which you should make configurable via constants. An example of this is removing {x} amount of objects at a time.
+* Add a flexible but secure set of entity access rules based on the module roles that you add. Keep in mind the use cases for your connector. Mendix recommends you avoid any persistable data.
## Configuration
-Configuration should ensure that your connector can be used in different settings without changes to the module itself. This means that upon deployment or after deployment your connector can be configured to connect to the relevant services.
+You should set up your configuration in such a way as to ensure that your connector can be used in different settings without changes to the module itself. This means that upon deployment or after deployment your connector can be configured to connect to the relevant services.
Using constants is the way to deal with configuration that aligns with the [Twelve-Factor Architecture](https://www.mendix.com/evaluation-guide/enterprise-capabilities/twelve-factor-architecture/) cloud-native approach.
@@ -258,33 +263,35 @@ When you are looking for a simple configuration, such as a URL, username, or pas
#### Simple Configuration with a Free App Environment
-When using constants in combination with a Free App, you can use the settings profile to allow for different configuration.
+When using constants in combination with a Free App, you can use the settings profile to allow for different configurations. Follow these steps to do that:
1. Create a constant.
- {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-constant.png" class="no-border" >}}
+ {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-constant.png">}}
2. Set the value of the constant to the value you want to use in your free cloud node.
- {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-value.png" class="no-border" >}}
+ {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-value.png" >}}
-3. Open your application **Settings**. Click **Duplicate** or **New** to create a new configuration for your local usage.
+3. Open your application **Settings**.
- {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-settings.png" class="no-border" >}}
+4. Click **Duplicate** or **New** to create a new configuration for your local usage.
-4. In your configuration, open the **Constants** tab and click **New**.
+ {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-settings.png">}}
- {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-new-constants.png" class="no-border" >}}
+5. In your configuration, open the **Constants** tab and click **New**.
-5. Look up and select your constant.
+ {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-new-constants.png">}}
- {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-select-constant.png" class="no-border" >}}
+6. Look up and select your constant.
-6. Change the configuration value of your constant to the value you want to use on your local environment.
+ {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-select-constant.png">}}
- {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-change-value.png" class="no-border" >}}
+7. Change the configuration value of your constant to the value you want to use in your local environment.
-7. Save all configuration and publish your application to your free node. When you run locally, Studio Pro will now use the **Active** configuration, while the free cloud node will keep using the value you specified in the **App Explorer**.
+ {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-change-value.png">}}
+
+8. Save the configuration and publish the application to your free node. When you run locally, Studio Pro will now use the **Active** configuration, while the free cloud node will keep using the value you specified in the **App Explorer**.
### Complex Configuration
@@ -294,71 +301,75 @@ You might need a more sophisticated configuration to connect to external systems
The following are the disadvantages of complex configuration:
-* Configuration in the database or the codebase means it is more difficult to deploy your connector/app just to any new environment
-* Manual configuration could cause more mistakes
-* Restoring a database to a different environment when the configuration is stored in the database could cause unwanted behavior
-
-One big risk of using the database to store configuration is something we have all seen go wrong at some point in time: test data going out to production users, or worse.
+* Configuration in the database or the codebase makes it difficult to deploy your connector/app to any new environment.
+* Manual configuration could cause more mistakes.
+* Restoring a database to a different environment when the configuration is stored in the database could cause unwanted behavior.
+* One big risk of using the database to store configuration is test data going out to production users.
#### Advantages of Complex Configuration
The following are the advantages of complex configuration:
-* More complex configuration then you could ever capture in constants
-* Easy runtime changes of the configuration
-* Option to add wizards/helper flows to guide the user with the configuration
+* It provides more complexity than constants.
+* You can easily perform runtime changes on the configuration.
+* You can add wizards/helper flows to guide the user with the configuration.
#### Setting Up Complex Configuration
-The following steps walk you through complex configuration:
+Follow these steps to set up complex configuration:
1. Set up a **Configuration** entity.
- {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/complex-config-entity.png" class="no-border" >}}
+ {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/complex-config-entity.png">}}
-2. Create the microflow. Have a single microflow called **DS_GetOrCreateSettings** that is the only place in your application to acquire your settings. This microflow would retrieve your settings from the database and creates it if this does exist with appropriate default values.
+2. Create the microflow.
+ Have a single microflow called **DS_GetOrCreateSettings**. It will retrieve your settings from the database, and create it with appropriate default values if it does not exist.
- {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/complex-config-create-microflow.png" class="no-border" >}}
+ {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/complex-config-create-microflow.png">}}
3. Set up security on the entity and the microflow.
- {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/complex-config-security.png" class="no-border" >}}
+ {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/complex-config-security.png" >}}
- {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/complex-config-security-2.png" class="no-border" >}}
+ {{< figure src="/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/complex-config-security-2.png" >}}
-4. Set up the administrator page. Have an administration page to manage the configuration. For maximum reusability, have all configuration settings available in a single snippet so your consumer can combine all admin sections from all components into a single area in their application.
+4. Set up the administrator page.
+ Have an administration page to manage the configuration. For maximum reusability, have all configuration settings available in a single snippet so your consumer can combine all admin sections from all components into a single area in their application.
5. Encrypt the password and other sensitive information.
##### Further Considerations
-When possible, create a microflow to set up the default or starting configuration for your consumers. Consider adding logic so you can code the configuration in a microflow to easily configure from your code base.
+When possible, create a microflow to set up the default or starting configuration for your consumers.
+
+Consider adding logic so the configuration can easily be set up from your codebase.
If possible, add an export/import option for the configuration to safely move the configuration between environments. This could be achieved via a JSON export/import of the configuration data.
## Security
-Security for components should be set up in a generic, granular, and secure way. When choosing your module roles, think about the most granular configuration, allowing end-users maximum flexibility in setting up roles.
+Security for components should be set up in a generic and granular way. When choosing your module roles, think about the most granular configuration which also allows end users maximum flexibility.
### Module Security
The following recommendations apply to module security:
-* Module roles should always be set up even if there is limited or no UI to allow the user to extend your component without having to customize.
-* Use clear granular roles, in which the role **Documentation** field clearly explains the purpose of each role.
+* Module roles should always be set up, even if there is limited or no UI to allow the user to extend your component without having to customize.
+* Use clear granular roles, in which the **Documentation** field clearly explains the purpose of each role.
* Keep security as simple as possible. Find a balance between granularity and simplicity.
-* Always keep configuration and data access separate. In most organizations, administrators should not have access to the data. If your organization is different, you can always combine module roles but consumers cannot split them.
+* Always keep configuration and data access separate.
+In most organizations, administrators should not have access to the data. If your organization is different, you can always combine module roles, but consumers cannot split them.
* Make sure to [implement best practices for app security](/howto/security/best-practices-security/).
-See [Module Security](/refguide/module-security/) for more detailed information.
+See [Module Security](/refguide/module-security/) for more details.
### Entity Security
-Think about how to apply access rules and read or write to your domain model. For example, if you do not give any rights to objects, you are telling the developer to use a data transformation layer and create their own objects to build their pages, or enrich their own objects with results coming from the connector.
+Think about how to apply access rules and read or write permissions to your domain model. For example, if you do not give any rights to objects, developers have to use a data transformation layer and create their own objects to build their pages, or enrich their own objects with results coming from the connector.
### Passwords and Other API keys
-If you store a password or API keys for your endpoint, always encrypt the password and API keys using the [Encryption](/appstore/modules/encryption/) module.
+If you store a password or API keys for your endpoint, always encrypt them using the [Encryption](/appstore/modules/encryption/) module.
### Typical Security Schemes
@@ -366,17 +377,20 @@ There are several security schemes you might encounter when building a connector
#### Client Credentials
-Security via client credentials is a very basic security method. Given that you use the login name and password, the only protection when sending it over to the service you are integrating with is an encrypted connection over SSL. If that is unavailable, make sure to never use this type of encryption.
+Security via client credentials is a very basic security method. Given that you use the login name and password, the only protection when sending it to the service you are integrating with is an encrypted connection over SSL. If that is unavailable, make sure to never use this type of encryption.
#### API Tokens
-API tokens help when securing an API. But an API payload sent in plain text could still be intercepted. Only use API tokens when you have at least an SSL connection.
+API tokens help when securing an API. However, an API payload sent in plain text could still be intercepted. Only use API tokens when you have at least an SSL connection.
#### OAuth
-OAuth comes in two types. In the first, an Authorization Code flow, the user does a login to the service providing the OAuth authentication to give access to their data on a per-user basis. The second type, with Client Credentials, provides a public and private key with access tokens for server-to-server communication.
+OAuth comes in two types:
-OAuth is a secure, because the secret key is never exchanged during API requests. As long as you store the secret key safely in your own app, it will not be possible to hijack your credentials for the API provider if you are using HTTPS.
+* An Authorization Code flow – The user logs in to the service through OAuth authentication, thus giving access to their data on a per-user basis.
+* Client Credentials – Provide a public and private key with access tokens for server-to-server communication.
+
+OAuth is a secure schema because the secret key is never exchanged during API requests. As long as you store the secret key safely in your own app, and you use HTTPS, your credentials for the API provider cannot be hijacked.
#### SAML
@@ -384,9 +398,9 @@ The [SAML](/appstore/modules/saml/) module, available on the Mendix Marketplace,
## Testing {#testing}
-You can test Mendix by calling microflows with the [Unit Testing](/appstore/modules/unit-testing/) module for whole pieces of functionality. Use unit tests for smaller, more targeted tests at the method-level of your Java code.
+You can use the [Unit Testing](/appstore/modules/unit-testing/) module to test Mendix by calling microflows for whole pieces of functionality. Use unit tests for smaller, more targeted tests at the method-level of your Java code.
-As with any automated testing, it is a great supplement for capturing known, expected behavior. For capturing known unknowns and unknown unknowns, Mendix recommends risk-based exploratory testing.
+As with any automated testing, it is a great supplement for capturing known, expected behavior. For capturing unknown behavior, Mendix recommends risk-based exploratory testing.
### Testing Microflows
@@ -403,9 +417,8 @@ The following tools are part of the testing process of custom Java code in your
* [JUnit](https://junit.org/junit5/) — This allows you to run Java unit tests easily.
* [Mockito](https://site.mockito.org/) — This allows you to mock Java classes. You can fake a class during a test so that it thinks that it deals with a real class, while it is actually just behaving like one.
* [JaCoCo](https://www.jacoco.org/jacoco/trunk/index.html) (Java Code Coverage) — This helps you check how well your code is covered by tests.
-* Gradle — This pulls everything together to manage Java dependencies, and provides a way to work with JUnit and Mockito.
-
-Gradle can handle managing Java dependencies and running [JUnit](https://junit.org) tests. Read about setting up Gradle in [Extending App Setup for Building Connectors with Java](#extend-app-java). If you have a pipeline, Mendix recommends running your tests as part of it.
+* [Gradle](https://gradle.org/) — This pulls everything together to manage Java dependencies, and provides a way to work with JUnit and Mockito.
+ Gradle can handle managing Java dependencies and running [JUnit](https://junit.org) tests. Read about setting up Gradle in [Extending App Setup for Building Connectors with Java](#extend-app-java). If you have a pipeline, Mendix recommends running your tests as part of it.
#### Using the Java Unit Test Reference
@@ -413,9 +426,9 @@ Mendix apps need `Core` classes, and the **Class Core** [Runtime API](/apidocs-m
Our [Java unit test reference](https://Github.com/mendixlabs/javaunittestreference) is available to help you through this process. `MendixUnitTestBase.java` is extendable and reusable for your own purposes. When extended, it enables Mockito on your test classes and mocks `Core` API behavior. This does the following:
-* Checks that your code sends a certain log message to a log node
-* Verifies that your code calls a microflow with correct parameters
-* Makes constants available to your Java code
+* Checks that your code sends a certain log message to a log node.
+* Verifies that your code calls a microflow with correct parameters.
+* Makes constants available to your Java code.
{{% alert color="info" %}}
The Java unit test reference has been tested up to and including Studio Pro [9.12](/releasenotes/studio-pro/9.12/).
@@ -423,7 +436,7 @@ The Java unit test reference has been tested up to and including Studio Pro [9.1
#### Writing Java Code
-When writing Java code, try to use as much Mendix-independent logic as possible. This helps with testability, so you do not have to mock Mendix Core to unit test the Java code.
+When writing Java code, try to use as much Mendix-independent logic as possible. This helps with testability, so you do not have to mock Mendix `Core` to unit test the Java code.
If you code the bulk of the behavior in generic Java classes that can run without Mendix, development and testing becomes a lot simpler and faster. There is no need to run your Mendix app to test, and you can also rely on Java JUnit tests for testing.
@@ -438,17 +451,17 @@ When calling a REST service, you can run into an error. This can be one of two t
If there is no response, the default error handling is enough. This will typically occur when the endpoint is down or when you get a timeout.
-If there is a response the error message will contain the error code and the reason, but not the message. For that reason, add an additional log message with the response and then rethrow the error. Add details about the request that will help the developer.
+If there is a response, the error message will contain the error code and the reason, but not the message. For that reason, add an additional log message with the response, then rethrow the error. The log message should include details about the request that will help the developer.
-Any input, such as objects or path parameters might trigger an error event in the REST call. It is unnecessary to check them for empty values in the connector itself. Make sure to check them for empty before using [urlEncode](/refguide/string-function-calls/#urlEncode).
+Any input, such as objects or path parameters, might trigger an error event in the REST call. It is not necessary to check them for empty values in the connector itself, but do make sure to check them before using [urlEncode](/refguide/string-function-calls/#urlEncode).
In some situations, the error response from the service has its own structure that you want to leverage. For example, when there is a bad request, you might want to pass that message back to the user instead of logging it. However, you cannot return two different objects from one microflow. In those situations, combine the response from the error message with the regular message. In all other situations, the error is unexpected, and you can return the error.
-## Release and Versioning
+## Releasing and Versioning
-This section addresses best practices for releasing your connector and using a versioning system. For the basic instructions for releasing, versioning, and distributing your connector, see the [Exporting the Connector](/appstore/creating-content/connector-guide-build/#export) and [Distributing the Connector](/appstore/creating-content/connector-guide-build/#distribute) sections of *Build Connectors*.
+This section addresses best practices for releasing your connector and using a versioning system. For the basic instructions for releasing, versioning, and distributing your connector, see the [Exporting the Connector](/appstore/creating-content/connector-guide-build/#export) and [Distributing the Connector](/appstore/creating-content/connector-guide-build/#distribute) sections of *Creating Connectors*.
-### Release
+### Releasing
Ensure a new release includes the following:
@@ -457,13 +470,13 @@ Ensure a new release includes the following:
### Versioning {#versioning}
-The [Update Existing Marketplace Content](/appstore/submit-content/#updating) section of *Share Marketplace Content* provides explanations of the recommended versioning system. The following points go into more detail on the versioning number system:
+The [Updating Existing Marketplace Content](/appstore/submit-content/#updating) section of *Uploading to the Marketplace* provides explanations of the recommended versioning system. The following points go into more detail on the versioning number system:
-* *Major version* — This is the first digit. This number goes up when you release major breaking changes, or at the very least a major new feature, as part of your connector. Determining what is major is up to you. You can deploy minor/patch versions for older major versions when you have bugs that need resolving.
+* Major version — This is the first digit. This number goes up when you release major breaking changes, or at the very least a major new feature, as part of your connector. Determining what is major is up to you. You can deploy minor/patch versions for older major versions when you have bugs that need resolving.
-* *Minor version* — This is the second digit. This number goes up when you release minor changes that do not break backwards compatibility, fixes some bugs, or adds small new features. Depending on your development cycle, this could be intermediate releases in smaller batches.
+* Minor version — This is the second digit. This number goes up when you release minor changes that do not break backwards compatibility, and that fix some bugs, or add small new features. Depending on your development cycle, this could be intermediate releases in smaller batches.
-* *Patch version* — This is the third digit. This number goes up when you really have to patch a bug for a specific version and it cannot be released as part of your next major or minor version. While it is allowed to add new patch versions to older major versions, you cannot add patch versions to older minor versions within the Marketplace.
+* Patch version — This is the third digit. This number goes up when you really have to patch a bug for a specific version and it cannot be released as part of your next major or minor version. While it is allowed to add new patch versions to older major versions, you cannot add patch versions to older minor versions within the Marketplace.
## Licensing
diff --git a/content/en/docs/appstore/create-content/create-modules/_index.md b/content/en/docs/appstore/create-content/create-modules/_index.md
index 3dea02ee986..85cfdbde7a9 100644
--- a/content/en/docs/appstore/create-content/create-modules/_index.md
+++ b/content/en/docs/appstore/create-content/create-modules/_index.md
@@ -1,39 +1,31 @@
---
-title: "Create Modules"
+title: "Creating Modules"
url: /appstore/guidelines-creating-modules/
description: "Describes guidelines for creating modules in the Marketplace."
weight: 3
tags: ["marketplace", "content creation", "guidelines", "modules"]
---
-## 1 Introduction
+## Introduction
-The guidelines to develop modules and submit them to the Marketplace as as follows:
-
-* Create a folder named **USE_ME** and add the microflows and pages that are relevant for the user.
+Follow these guidelines when developing modules and submitting them to the Marketplace:
+* Create a folder named **USE_ME**, and add the microflows and pages that are relevant for the user.
* Create an empty folder with the version number as its name, which will appear in Studio Pro's App Explorer.
+* For Java dependencies, follow these guidelines:
-* For Java dependencies, follow the following guidelines:
-
- * In versions Mendix 10.3.0 and above, use [managed dependencies](/refguide/managed-dependencies/) where possible. For versions below 10.3, ensure that Java dependencies are put in the `userlib` folder. You should also put any [unmanaged dependencies](/refguide/managed-dependencies/#unmanaged), that is, non-publicly-available *.jar* files, in the **userlib** folder.
+ * In versions Mendix 10.3.0 and above, use [managed dependencies](/refguide/managed-dependencies/) where possible.
+ * In versions below 10.3, ensure that Java dependencies are put in the `userlib` folder. You should also put any [unmanaged dependencies](/refguide/managed-dependencies/#unmanaged), that is, non-publicly-available *.jar* files, in the **userlib** folder.
- * When putting *.jar* files in the **userlib** folder, make sure the name includes a version number (for example, `org.apache.commons.io-2.3.0.jar`) and is accompanied by a blank `{jarfile-including-version}.{module_name}.RequiredLib` file so that users know where the .*jar* files come from (for example, for the module *MyModule*, `org.apache.commons.io-2.3.0.jar.MyModule.RequiredLib`).
+ * When putting *.jar* files in the **userlib** folder, make sure that the name includes a version number (for example, `org.apache.commons.io-2.3.0.jar`), and that it is accompanied by a blank `{jarfile-including-version}.{module_name}.RequiredLib` file. This is so users know where the .*jar* files come from. For example, for the *MyModule* component, this would be `org.apache.commons.io-2.3.0.jar.MyModule.RequiredLib`.
- {{< figure src="/attachments/appstore/submit-content/userlibBlankFiles_boxed.jpg" width="400" >}}
+ {{< figure src="/attachments/appstore/submit-content/userlibBlankFiles_boxed.jpg">}}
* Verify that the module's Java actions compile correctly. The easiest way to check is to create a deployment package, as it will clean the deployment folder and rebuild the app. For more information, see [Environments](/developerportal/deploy/environments/).
-
-* Reduce the use of layouts and use snippets instead, which will result in fewer module dependencies and will reduce the number of potential errors (for example, missing layouts).
-
-* Implement [user roles](/refguide/user-roles/) and [security.](/refguide/security/)
-
-* Creating a new release or module export should be done while the security level of the app containing the module is set to *Production*.
-
+* Reduce the use of layouts and use snippets instead. This results in fewer module dependencies, and reduces the number of potential errors, such as missing layouts.
+* Implement [user roles](/refguide/user-roles/) and [security](/refguide/security/).
+* Creating a new release or module export only while the security level of the app containing the module is set to *Production*.
* The [status](/refguide/app-security/#app-status) must be **Complete** for the following access: page, microflow, OData, entity, and dataset.
-
-* For example pages and microflows to be copied to another module, select the **Exclude from project** option for the document in order to encourage duplication and reduce dependency errors .
-
-* Do not rename entities and attributes when creating new versions, as data in these entities will get lost (replacing an existing module is based on the entity names).
-
+* For example pages and microflows to be copied to another module, select the **Exclude from project** option for the document. This encourages duplication and reduces dependency errors.
+* Do not rename entities and attributes when creating new versions, as data in these entities will get lost. Replacing an existing module is based on the entity names.
* The module must include the English language.
diff --git a/content/en/docs/appstore/create-content/create-solutions/_index.md b/content/en/docs/appstore/create-content/create-solutions/_index.md
index 75464edd30d..1a456c9e1f5 100644
--- a/content/en/docs/appstore/create-content/create-solutions/_index.md
+++ b/content/en/docs/appstore/create-content/create-solutions/_index.md
@@ -1,7 +1,7 @@
---
-title: "Create Solutions"
+title: "Creating Solutions"
url: /appstore/creating-content/sol-solutions-guide/
-linktitle: "Create Solutions"
+linktitle: "Creating Solutions"
weight: 5
description: "Provides information and guidance on how to develop solutions you can sell both on and off the Mendix Marketplace."
#If moving or renaming this doc file, implement a temporary redirect and let the respective team know they should update the URL in the product. See Mapping to Products for more details.
@@ -9,11 +9,11 @@ description: "Provides information and guidance on how to develop solutions you
## Introduction
-This section provides information and guidance on how to develop solutions you can sell both on and off the Mendix Marketplace.
+This section provides information and guidance on how to develop solutions that you can sell both on and off the Mendix Marketplace.
## What Is a Solution?
-A solution is any Mendix app that is suitable to be sold to multiple different customers. This means the app is built to match the needs and expectations of a wider range of customers. Sometimes this means the app is configurable at runtime to better cater to the needs of groups of customers. In this case, general Mendix development [best practices](/refguide/dev-best-practices/) apply, and you can get started building a solution with any template available on the Mendix Platform.
+A solution is any Mendix app that is suitable to be sold to multiple different customers. This means the app is built to match the needs and expectations of a wider range of customers, and also configurable at runtime to better cater to their needs. In this case, general Mendix development [best practices](/refguide/dev-best-practices/) apply, and you can get started building a solution with any template available on the Mendix Platform.
Customers often require more from a solution than it supports out of the box. Whether it is an integration with an existing system in the customer's IT landscape, a change to better match the processes of the customer, or simply an adjusted UI to better match the brand of the customer, these adaptations require more than just a prescriptive software-as-a-service (SaaS) solution. This means you need to enable the solution to be adapted so that it can fit the specific needs of a customer.
@@ -21,10 +21,10 @@ For more details on how to combine out-of-the-box logic with customer adaptation
## Read More
-If you are looking to publish premium components, take a look at the details of the [Mendix Component Partner Program](/appstore/partner-program/).
+* If you are looking to publish premium components, take a look at the details of the [Mendix Component Partner Program](/appstore/partner-program/).
-If you are looking to build and market commercial solutions, look into the [Mendix Commercial Solution Partner Program](/appstore/creating-content/comm-sol-partner-program/).
+* If you are looking to build and market commercial solutions, look into the [Mendix Commercial Solution Partner Program](/appstore/creating-content/comm-sol-partner-program/).
-Then, proceed to [Introduction to Adaptable Solutions](/appstore/creating-content/sol-adapt/), which presents principles and best practices for developing solutions on the Mendix Platform that are ready to be sold on the Marketplace.
+* Then, proceed to [Introduction to Adaptable Solutions](/appstore/creating-content/sol-adapt/), which presents principles and best practices for developing solutions on the Mendix Platform that are ready to be sold on the Marketplace.
-After reading through these pages, [create your app](https://new.mendix.com/) and Go Make It!
+* After reading through these pages, [create your app](https://new.mendix.com/) and Go Make It!
diff --git a/content/en/docs/appstore/create-content/create-solutions/implement-solutions/_index.md b/content/en/docs/appstore/create-content/create-solutions/implement-solutions/_index.md
index bdefa16d05c..ebb83e10d4b 100644
--- a/content/en/docs/appstore/create-content/create-solutions/implement-solutions/_index.md
+++ b/content/en/docs/appstore/create-content/create-solutions/implement-solutions/_index.md
@@ -1,7 +1,7 @@
---
-title: "Implement a Solution"
+title: "Implementing Solutions"
url: /appstore/creating-content/sol-solutions-impl/
-linktitle: "Implement Solutions"
+linktitle: "Implementing Solutions"
weight: 30
description: "Provides information and guidance on how to implement Mendix solutions."
#If moving or renaming this doc file, implement a temporary redirect and let the respective team know they should update the URL in the product. See Mapping to Products for more details.
@@ -27,13 +27,13 @@ There are three main stages a solution goes through during its lifecycle:
As the **Build** stage is an iterative process, a new version is periodically released by the ISV. In the **Implement** stage, the implementer needs to incorporate the changes from this new version into the current implementation.
-To be able to implement, you must set up the solution in the proper way to enable future upgrades to new versions provided by the ISV. For more information, see [Set Up a Solution](/appstore/creating-content/sol-set-up/).
+To be able to implement, you must set up the solution in the proper way to enable future upgrades to new versions provided by the ISV. For more information, see [Setting Up Solutions](/appstore/creating-content/sol-set-up/).
-For details on the upgrade procedure for a solution that has been set up correctly, see [Upgrade a Solution](/appstore/creating-content/sol-upgrade/).
+For details on the upgrade procedure for a solution that has been set up correctly, see [Upgrading Solutions](/appstore/creating-content/sol-upgrade/).
## Read More
-* [Develop a Solution](/appstore/creating-content/sol-adapt/)
-* [Architect an Adaptable Solution](/appstore/creating-content/sol-architecting/)
-* [Set Up a Solution](/appstore/creating-content/sol-set-up/)
-* [Upgrade a Solution](/appstore/creating-content/sol-upgrade/)
+* [Adaptable Solutions](/appstore/creating-content/sol-adapt/)
+* [Architecting Adaptable Solutions](/appstore/creating-content/sol-architecting/)
+* [Setting Up Solutions](/appstore/creating-content/sol-set-up/)
+* [Upgrading Solutions](/appstore/creating-content/sol-upgrade/)
diff --git a/content/en/docs/appstore/create-content/create-solutions/implement-solutions/sol-set-up.md b/content/en/docs/appstore/create-content/create-solutions/implement-solutions/sol-set-up.md
index c4b4d2400a4..d90274e0f86 100644
--- a/content/en/docs/appstore/create-content/create-solutions/implement-solutions/sol-set-up.md
+++ b/content/en/docs/appstore/create-content/create-solutions/implement-solutions/sol-set-up.md
@@ -1,22 +1,23 @@
---
-title: "Set Up a Solution"
+title: "Setting Up Solutions"
url: /appstore/creating-content/sol-set-up
-linktitle: "Set Up a Solution"
-weight: 10
+linktitle: "Setting Up Solutions"
+weight: 8
description: "Describes properly initializing a Mendix solution to be compatible with future upgrades."
---
## Introduction
-Setting up a Mendix solution is the process of creating your app from the solution package and configuring it to be compatible with future upgrades.
+Setting up a Mendix solution is the process of creating your app from the solution package, and configuring it to be compatible with future upgrades.
## Prerequisites
To set up a Mendix solution, make sure the following prerequisites are met:
-* A solution can only be set up with the Studio Pro version that exactly matches the version used to create it (for example, if Studio Pro 10.0 was used to create the solution, only that version can be used to set up the solution), so make sure you are using the correct Studio Pro version
-* The solution must be version-controlled with Git so that it is compatible with upgrades
-* It is impossible to initialize a solution on a non-empty repository
+* Make sure you are using the correct Studio Pro version.
+ A solution can only be set up with the Studio Pro version that exactly matches the version used to create it. For example, if Studio Pro 10.0 was used to create the solution, only that version can be used to set up the solution.
+* The solution must be version-controlled with Git so that it is compatible with upgrades.
+* Make sure your repository is empty. It is impossible to initialize a solution on a non-empty repository.
## Setup Process
@@ -27,8 +28,8 @@ To set up a solution, follow these steps:
{{< figure src="/attachments/appstore/create-content/implement-solutions/solution-import.png" alt="Import Solution" class="no-border" >}}
2. Select the target directory for your solution and click **OK**.
-3. Once the solution is initialized, a special **solution-releases** branch is created. This branch contains the unchanged version of the solution (as provided by the ISV). You cannot make any changes in this branch, as that would render the solution incompatible with upgrades or lead to unpredictable errors during upgrades.
+3. Once the solution is initialized, a special **solution-releases** branch is created. This branch contains the unchanged version of the solution, as provided by the ISV. You cannot make any changes in this branch, as that would render the solution incompatible with upgrades, or lead to unpredictable errors during upgrades.
### Read More
-* [Upgrade a Solution](/appstore/creating-content/sol-upgrade/)
+* [Upgrading Solutions](/appstore/creating-content/sol-upgrade/)
diff --git a/content/en/docs/appstore/create-content/create-solutions/implement-solutions/sol-upgrade.md b/content/en/docs/appstore/create-content/create-solutions/implement-solutions/sol-upgrade.md
index f9b652f3950..9113fd8b5be 100644
--- a/content/en/docs/appstore/create-content/create-solutions/implement-solutions/sol-upgrade.md
+++ b/content/en/docs/appstore/create-content/create-solutions/implement-solutions/sol-upgrade.md
@@ -1,8 +1,8 @@
---
-title: "Upgrade a Solution"
+title: "Upgrading Solutions"
url: /appstore/creating-content/sol-upgrade
-linktitle: "Upgrade a Solution"
-weight: 8
+linktitle: "Upgrading Solutions"
+weight: 10
description: "Describes how to upgrade a properly set up solution with a new version provided by the ISV."
---
@@ -14,14 +14,15 @@ Upgrading a solution is the process of merging changes provided by the ISV into
To upgrade a Mendix solution, make sure the following prerequisites are met:
-* You are using the same Studio Pro version as the version used to create the solution package (for example, if Studio Pro 10.0 was used to create the solution, only that version can be used to upgrade the solution)
-* Your version control system is Git
-* Your app is currently on the **main** branch line
-* The **solution-releases** branch line exists
-* There are no uncommitted changes or unresolved conflicts in your app
-* There is only one MPR file in the solution package
-* The name of your app's MPR file is the same as the name of the MPR file in the solution package
-* The solution you are upgrading to is the same solution that was used to set up your adaptable solution
+* Make sure you are using the correct Studio Pro version.
+ A solution can only be set up with the Studio Pro version that exactly matches the version used to create it. For example, if Studio Pro 10.0 was used to create the solution, only that version can be used to set up the solution.
+* Your version control system is Git.
+* Your app is currently on the **main** branch line.
+* The **solution-releases** branch line exists.
+* There are no uncommitted changes or unresolved conflicts in your app.
+* There is only one MPR file in the solution package.
+* The name of your app's MPR file is the same as the name of the MPR file in the solution package.
+* The solution you are upgrading to is the same solution that was used to set up your adaptable solution.
{{% alert color="info" %}}You can consider skipping versions when upgrading. For example, if you set up your solution with v1 and the ISV then released v2 and v3, it is not necessary for you to upgrade versions one by one. You can go directly from v1 to v3 if there were no data migration changes in v2.{{% /alert %}}
@@ -33,7 +34,11 @@ To upgrade a solution, follow these steps:
{{< figure src="/attachments/appstore/create-content/implement-solutions/solution-upgrade.png" alt="Upgrade Solution" class="no-border" >}}
- {{% alert color="info" %}}In Studio Pro 9 and below, this option must be enabled by setting a feature flag. Since Studio Pro 10, it is available for general use and no longer hidden behind a flag.{{% /alert %}}
+ {{% alert color="info" %}}In Studio Pro 9 and below, this option must be enabled by setting a feature flag. Since Studio Pro 10, it is available for general use, and no longer hidden behind a flag.{{% /alert %}}
2. Select the solution package file (*.mxsolution*) provided by the ISV and click **OK**.
-3. Once solution upgrade is completed, a new commit to the **solution-releases** branch line is created. This commit contains the unchanged new version of the solution (as provided by the ISV). You cannot make any changes in this branch, as that would render the solution incompatible with upgrades or lead to unpredictable errors during upgrades.
+3. Once the solution upgrade is completed, a new commit to the **solution-releases** branch line is created. This commit contains the unchanged new version of the solution, as provided by the ISV. You cannot make any changes in this branch, as that would render the solution incompatible with upgrades, or lead to unpredictable errors during upgrades.
+
+### Read More
+
+* [Setting Up Solutions](/appstore/creating-content/sol-set-up/)
\ No newline at end of file
diff --git a/content/en/docs/appstore/create-content/create-solutions/sol-adapt/_index.md b/content/en/docs/appstore/create-content/create-solutions/sol-adapt/_index.md
index a27bf504d62..ed508a77510 100644
--- a/content/en/docs/appstore/create-content/create-solutions/sol-adapt/_index.md
+++ b/content/en/docs/appstore/create-content/create-solutions/sol-adapt/_index.md
@@ -1,5 +1,5 @@
---
-title: "Introduction to Adaptable Solutions"
+title: "Adaptable Solutions"
url: /appstore/creating-content/sol-adapt/
weight: 20
no_list: false
@@ -9,7 +9,7 @@ description: "Presents introductory information on adaptable solutions."
## Introduction
-This section provides information and best practices on how to develop adaptable solutions on the Mendix Platform that are ready to be sold on the Mendix Marketplace.
+This section provides information and best practices on how to develop adaptable solutions on the Mendix Platform so they are ready to be sold in the Mendix Marketplace.
While [Mendix best practices for development](/refguide/dev-best-practices/) apply, there are additional considerations when [architecting](/appstore/creating-content/sol-architecting/) and developing a Mendix solution.
@@ -21,7 +21,7 @@ In an adaptable solution, up to 20% of the end solution can be adapted through c
## Use Cases
-As a concept, adaptable solutions work both for ISVs (for example, in the [Mendix Commercial Solution Partner Program](/appstore/creating-content/comm-sol-partner-program/)) and in the enterprise context.
+Adaptable solutions work both for ISVs, as is the case for the [Mendix Commercial Solution Partner Program](/appstore/creating-content/comm-sol-partner-program/), and in the enterprise context.
### ISV Commercial Solutions
@@ -29,7 +29,9 @@ ISVs can create and sell solutions that can be adapted for every individual cust
### Enterprise Context
-In larger enterprises, a typical situation occurs in which various departments or regionals have the same need, but they are also (slightly) different from each other. Adaptable solutions allow for the centralized development of the core solution while different teams can make adaptations themselves. Through upgrades, the centralized team can push common functionality to the different teams. An IP-protected and immutable core ensures that the implementation teams only adapt what is needed in order to minimize the impact of upgrades and adaptation effort.
+In larger enterprises, a common occurrence is having various different departments or regionals with the same need. Adaptable solutions allow for the centralized development of the core solution, while different teams can make adaptations themselves.
+
+Through upgrades, the centralized team can push common functionality to the different teams. An IP-protected and immutable core ensures that the implementation teams only adapt what is needed in order to minimize the impact of upgrades and the adaptation effort.
## Solution Lifecycle {#lifecycle}
@@ -47,7 +49,7 @@ The solution lifecycle can be visualized in this diagram:
### Implementation as a Separate Model Instance and Cloud Node
-The customer implementation is a separate upgradable model instance (fork) per customer that shares generic functionality from the original solution model and that is deployed to separate cloud resources.
+The customer implementation is a separate upgradable model instance (fork). It shares generic functionality with the original solution model, and is deployed to separate cloud resources.
{{< figure src="/attachments/appstore/create-content/create-solutions/sol-adapt/solution-deployment.png" alt="Adaptable Solution Deployment" width="50%" class="no-border" >}}
@@ -59,9 +61,9 @@ It is at the solution developer's discretion to determine who can implement a so
For more details, see the [Implementation per Customer](/appstore/creating-content/sol-architecting/#per-customer) section of *How to Architect Adaptable Solutions*.
-## Three Parts (Core, Adaptations, Extensions) {#three-parts}
+## Three Parts: Core, Adaptations, Extensions {#three-parts}
-Architecting a solution for adaptation requires an understanding of your customers' needs. You need to know which functional requirements are common across your customers and which are specific to individual customers. This enables grouping the modules in the application model into three main functional parts:
+Conceiving a solution for adaptation requires an understanding of your customers' needs. You need to know which functional requirements are common across your customers and which are specific to individual customers. This enables grouping the modules in the application model into three main functional parts:
* A shared and immutable common core
* Common modules that can be adapted to a customer’s needs
@@ -69,7 +71,7 @@ Architecting a solution for adaptation requires an understanding of your custome
{{< figure src="/attachments/appstore/create-content/create-solutions/sol-adapt/solution-three-parts.png" alt="Three parts of the adaptable solution" class="no-border" >}}
-These different parts work together in the customer implementation. It is important to maintain these distinctions, because there is an inherent tradeoff: What is part of the common core and IP-protected cannot be adapted or modified, while what can be adapted can never be protected. This boundary can be created at a fine-grained level. All adaptation (both extensions and adaptable core) can make use of functionality from the common core. For more information, see the [Application Design](/appstore/creating-content/sol-architecting/#app-design) section of *How to Architect Adaptable Solutions*.
+These different parts work together in the customer implementation. It is important to maintain these distinctions, because there is an inherent tradeoff: what is part of the common core and IP-protected cannot be adapted or modified, while what can be adapted can never be protected. This boundary can be created at a fine-grained level. All adaptations done to extensions and to the adaptable core can make use of functionality from the common core. For more information, see the [Application Design](/appstore/creating-content/sol-architecting/#app-design) section of *How to Architect Adaptable Solutions*.
This table describes the three main functional parts in more detail:
@@ -81,6 +83,6 @@ This table describes the three main functional parts in more detail:
## IP Protection {#ip-protection}
-To ensure that the intellectual property (IP) that is created during the [building the solution core](#lifecycle) phase is not disclosed to implementation teams or customers, you can [apply IP protection](/appstore/creating-content/sol-ip-protection/). This will also render those components immutable and make it easier to upgrade, as there will never be any merge conflicts.
+To ensure that the intellectual property (IP) that is created while [building the solution core](#lifecycle) is not disclosed to implementation teams or to customers, you can [apply IP protection](/appstore/creating-content/sol-ip-protection/). This will also render those components immutable, and make it easier to upgrade, as there will never be any merge conflicts.
## Documents in This Section
diff --git a/content/en/docs/appstore/create-content/create-solutions/sol-adapt/sol-adaptability.md b/content/en/docs/appstore/create-content/create-solutions/sol-adapt/sol-adaptability.md
index 1a24f50ebae..53cd5343e48 100644
--- a/content/en/docs/appstore/create-content/create-solutions/sol-adapt/sol-adaptability.md
+++ b/content/en/docs/appstore/create-content/create-solutions/sol-adapt/sol-adaptability.md
@@ -8,24 +8,26 @@ description: "Best practices for creating a solution for adaptation"
## Domain Model
-The sections below describe best practices for your solution's domain model.
+The following sections describe best practices for your solution's domain model.
### Solution Module Defining the Data Model Core
-Mendix recommends having the majority of your data model defined within solution modules in order to ensure stability. This also helps to maintain a clear separation between which entities, attributes, and associations come from the publisher and what is added during implementation. Finally, this also enables doing internal refactoring without having to take all customer instances into account.
+Mendix recommends having the majority of your data model defined within solution modules in order to ensure stability. This also helps maintain a clear separation between which entities, attributes, and associations come from the publisher, and what is added during implementation. It also enables internal refactoring without having to take all customer instances into account.
### Extension Through Extension Entities (Composition Pattern or Specializations)
In general, Mendix recommends using a separate extension entity with a one-to-many or one-to-one relationship owned by the core entity. This enables adding additional attributes and associations during the implementation. Using a separate entity also allows for the introduction or removal of extension capabilities without large data migration.
-Alternatively, it is possible to use specializations. Mendix recommends considering this as an alternative when the composition pattern does not solve the need.
+You can also use specializations. Mendix recommends considering this as an alternative when the composition pattern does not solve the need.
-| | Composition | Specializations |
+This table outlines the main differences between composition patterns and specializations:
+
+| Feature | Composition | Specializations |
| --- | --- | --- |
| **Easy to apply without data changes** | Yes, new extension objects can be created and linked to already existing core objects. | No, objects need to be re-created in order to change the entity/specialization type. |
| **Flexibility on security** | Core and extension have their own security rules. Core rules cannot be overridden. | Specialization allows for redefining security rules, even for entities that are defined inside solution modules. |
-| **Multiple extension versions** (for example, `Vehicle` becomes both `Car` and `Train`). | Setup can be complex. | More suitable. |
-| **Offline synchronization** | Fully supported. | Restrictions apply (for details, see [Offline Best Practices](/refguide/mobile/building-efficient-mobile-apps/offlinefirst-data/best-practices/#inheritance)). |
+| **Multiple extension versions** (for example, `Vehicle` becomes both `Car` and `Train`) | Setup can be complex. | More suitable. |
+| **Offline synchronization** | Fully supported. | Restrictions apply. For details, see [Offline Best Practices](/refguide/mobile/building-efficient-mobile-apps/offlinefirst-data/best-practices/#inheritance). |
### Example
@@ -35,20 +37,20 @@ Here is an example:
In this example, the following details apply:
-* **Company** is extended through composition, because that is the recommended approach and there are no requirements to reconsider. Additional entities can be created and linked (such as, the **AccountManager**).
-* **Vehicle** is extended through specializations, because every customer can have multiple vehicle types (for example, car, train).
+* **Company** is extended through composition, because that is the recommended approach and there are no requirements to reconsider. Additional entities, such as the **AccountManager**, can be created and linked.
+* **Vehicle** is extended through specializations, because every customer can have multiple vehicle types, such as car, train etc.
* **Task** is extended through a specialization, because every customer has very unique requirements on entity access.
* **Logo** is not extensible.
## Making Part of the Logic Adaptable
-You can make logic (microflows, nanoflows, and workflows) adaptable by placing documents into the open application modules. By using sub-flows, you can decide whether the entire flow can be adapted, or only specific parts thereof.
+You can make logic, that is microflows, nanoflows, and workflows, adaptable by placing documents into the open application modules. By using sub-flows, you can decide whether the entire flow can be adapted, or only specific parts of it.
-| Purpose | Calling Flow | Called (Sub-) Flow |
+| Purpose | Calling Flow | Called (Sub-)Flow |
| --- | --- | --- |
-| Split (re-) usable core logic into (reusable) microflows | Solution module (usable) | Open application module |
-| Make part of hidden core logic adaptable | Solution module (hidden) | Open application module |
-| Make part of (re-) usable core adaptable | Solution module (usable) | Open application module |
+| Split (re-)usable core logic into (reusable) microflows | Solution module (usable) | Open application module |
+| Make part of the hidden core logic adaptable | Solution module (hidden) | Open application module |
+| Make part of the (re-)usable core adaptable | Solution module (usable) | Open application module |
| Reuse core logic in an adaptable microflow | Open application module | Solution module (usable) |
| Split adaptable microflow | Open application module | Open application module (newly created flow) |
@@ -58,12 +60,12 @@ All document types can be part of the solution module, but only nanoflows, micro
## Creating an Adaptable UI
-The same patterns that can be used for microflows can be used for making pages (partially) adaptable. For this, you can use a combination of (hidden) pages, editable layouts, and snippets.
+The same patterns that can be used for microflows can be used for making pages adaptable or partially adaptable. For this, you can use a combination of pages, editable layouts, and snippets, which can also be hidden.
-| | Open App Module/UI Resource Module | Solution Module |
+| Object | Open App Module/UI Resource Module | Solution Module |
| --- | --- | --- |
| **Page** | Adaptable pages. | Core pages can be hidden and called through microflows and nanoflows. |
-| **Snippet** | Making (parts) of the UI adaptable. | Core snippets can be hidden as long as it is for reuse in hidden core pages. |
+| **Snippet** | Make parts of the UI or the entire UI adaptable. | Core snippets can be hidden as long as it is for reuse in hidden core pages. |
| **Layout** | Main layout for the application. Use a solution-specific [master layout](/refguide/layout/#master-layout) to enable changing the layout of all (adaptable and hidden) pages by the customer. | Core layouts can be hidden and use an adaptable master layout. |
| **Building block** | Building blocks that are supposed to be used during adaptation need to reside in an open module. | Building blocks that are used during development of the core solution can be hidden. |
| **SASS files** | Define the theme and look and feel of your app. | No SASS definition support. Usage of existing theme and design properties as well as additional styling can be done through inline styling only. |
@@ -74,7 +76,9 @@ The app title, favicon, and login pages are always adaptable, since they live at
### Cascading Theming Modules
-For solution development, Mendix recommends using a layered approach to your theme modules to make them as adaptable as possible (for more information, see the [Brand Your Adaptable Solution](https://academy.mendix.com/link/paths/130/Brand-your-Adaptive-Solution) learning path, which includes details on how to structure your SASS files).
+For solution development, Mendix recommends using a layered approach to your theme modules to make them as adaptable as possible.
+
+For more information, see the [Brand Your Adaptable Solution](https://academy.mendix.com/link/paths/130/Brand-your-Adaptive-Solution) learning path, which includes details on how to structure your SASS files.
An ISV that maintains multiple adaptable solutions can structure their theme modules in the following way:
@@ -87,32 +91,36 @@ An ISV that maintains multiple adaptable solutions can structure their theme mod
| Customer app- specific | Customer implementation team | Customer implementation of a specific solution of the ISV | Overriding the styling for a specific customer instance |
{{% alert color="info" %}}
-For an ISV with a single solution, this can be reduced to three modules (Atlas Core, ISV theme, and customer theme).
+For an ISV with a single solution, this can be reduced to three modules:
+
+* Atlas Core
+* ISV theme
+* Customer theme
{{% /alert %}}
-In general, Mendix recommends being explicit regarding the used design system (and creating the relevant building blocks) to allow for a consistent look and feel across the adaptation and core UI.
+In general, Mendix recommends being explicit regarding the used design system, and creating the relevant building blocks. This allows for a consistent look and feel across the adaptation and core UI.
## Using Constants
-The default value of a usable constant cannot be overridden at implementation, but the local Studio Pro value can be changed using the [Mendix Runtime settings](/developerportal/deploy/environments-details/#constants). Constants can always be configured as part of the environment settings (including hidden constants).
+The default value of a usable constant cannot be overridden at implementation, but the local Studio Pro value can be changed using the [Mendix Runtime settings](/developerportal/deploy/environments-details/#constants). Constants, included hidden constants, can always be configured as part of the environment settings.
For more information, see [Constant Default Value](/refguide/constants/#default-value) in the *Studio Pro Guide*.
## Translating the Implementation and Implementing Jargon
-In order to make the application translatable during implementation, all translatable documents need to be stored in open application modules. Using the [batch translate](/refguide/batch-translate/) and [batch replace](/refguide/batch-replace/) features, the text can be translated or updated during implementation. This can be done, for example, to implement jargon by changing a default concept like “Asset” into a customer-specific word such as “Car” .
+To make the application translatable during implementation, all translatable documents need to be stored in open application modules. Using the [batch translate](/refguide/batch-translate/) and [batch replace](/refguide/batch-replace/) features, the text can be translated or updated during implementation. This can be done, for example, to implement jargon by changing a default concept like “Asset” into a customer-specific word like “Car” .
{{% alert color="info" %}}
Only adaptable content can be translated, since protected content is locked down.
{{% /alert %}}
-Variables cannot (easily) be translated, nor can text be changed in a protected microflow (since this is locked down). As a workaround for this, consider using an editable Enumeration as an “internationalization map” combined with the [getCaption](/refguide/enumerations-in-expressions/#getCaption) function.
+Variables cannot easily be translated, nor can text be changed in a protected microflow, since this is locked down. As a workaround, consider using an editable Enumeration as an internationalization map combined with the [getCaption](/refguide/enumerations-in-expressions/#getCaption) function.
## Java Source Code Protection
-Setting the export level to **Hidden** on a Java action prevents the unpacking of the action in the app directory in the same path as regular modules. Your Java code is put in a package, but no obfuscation or other security measures take place. This means that reverse engineering the package would reveal your source code.
+Setting the export level to **Hidden** on a Java action prevents the action from being unpacked in the app directory at the same path as regular modules. Your Java code is put in a package, but no obfuscation or other security measures take place. This means that reverse engineering the package would reveal your source code.
-Mendix does not offer a facility to further protect intellectual property in your Java files. For further protection, Mendix recommends using other software (for example, to obfuscate your source code).
+Mendix does not offer a facility to further protect intellectual property in your Java files. For further protection, such as to obfuscate your source code, Mendix recommends using other software.
## Read More
diff --git a/content/en/docs/appstore/create-content/create-solutions/sol-adapt/sol-architecting.md b/content/en/docs/appstore/create-content/create-solutions/sol-adapt/sol-architecting.md
index f8a7e1d2d9e..497351d3887 100644
--- a/content/en/docs/appstore/create-content/create-solutions/sol-adapt/sol-architecting.md
+++ b/content/en/docs/appstore/create-content/create-solutions/sol-adapt/sol-architecting.md
@@ -1,7 +1,7 @@
---
-title: "Architect Adaptable Solutions"
+title: "Architecting Adaptable Solutions"
url: /appstore/creating-content/sol-architecting/
-linktitle: "Architect Solutions"
+linktitle: "Architecting Solutions"
weight: 1
description: "Architect a solution for adaptation"
---
@@ -12,15 +12,13 @@ The Mendix Platform is well-suited to supporting the development of solutions. R
## Progressive and Emergent Architecture
-The goal for architecting a solution for adaptation is a deep understanding and full specification of the correct scoping of the [three solution parts](/appstore/creating-content/sol-adapt/#three-parts) (meaning, the immutable core, customizable modules, and customer-specific components). This is a level of knowledge you will only reach once you are serving a large number of customers.
+The goal for architecting a solution for adaptation is a deep understanding and correct scoping of the [three solution parts](/appstore/creating-content/sol-adapt/#three-parts): the immutable core, the customizable modules, and the customer-specific components.
-When you start work on a solution for an initial customer or handful of customers, you might not have this thorough understanding. Instead, as you deliver the solution to additional customers, you will learn about their needs and will better understand which functionalities will be common and which will be specific.
-
-This requires an iterative approach, where your understanding of the architectural requirements becomes clearer over time. It also requires a certain level of pragmatism in technical design choices, because you have to accept that you do not know everything up-front and you will have to redo certain design choices as your understanding increases.
+This requires an iterative approach, where your understanding of the architectural requirements becomes clearer over time. It also requires a certain level of pragmatism in technical design choices, because you have to accept that you do not know everything upfront, and you will have to redo certain design choices as your understanding increases.
## Implementation per Customer {#per-customer}
-The customer implementation is a separate, upgradable model instance (fork) per customer that shares generic functionality from the original solution model and that is deployed to separate cloud resources. This allows the implementation team to fully customize all the functionality that is not IP-protected. Not all customer implementations require changes to the model. In those cases, the original model can be deployed as is. Depending on the use case, the customer gains access to the app as well.
+The customer implementation is a separate upgradable model instance (fork). It shares generic functionality with the original solution model, and is deployed to separate cloud resources. This allows the implementation team to fully customize all the functionality that is not IP-protected. Not all customer implementations require changes to the model. In those cases, the original model can be deployed as is. Depending on the use case, the customer gains access to the app as well.
### Summary
@@ -34,47 +32,47 @@ The customer implementation is a separate, upgradable model instance (fork) per
### Configuration and Adaptation
-As discussed in the [Solution Lifecycle](/appstore/creating-content/sol-adapt/#lifecycle) section of *Introduction to Adaptable Solutions*, the solution can be tailored to the customer’s need.
+As mentioned in the [Solution Lifecycle](/appstore/creating-content/sol-adapt/#lifecycle) section of *Adaptable Solutions*, the solution can be tailored to the customer’s need.
Mendix recommends using the following:
-* **Runtime configuration** (using [database setting objects](/refguide/custom-settings/#database-settings), or [constants](/refguide/constants/)) when configuring for the needs of customer groups. This should be used for light configuration and personalization through developer-built flexibility.
- * Enable/disable business processes
- * Conditionally make capabilities available (for example, feature toggles)
- * Parameterize capabilities for groups of customers (for example, configurable thresholds)
-* **Design-time adaptation** for changing the application model to the needs of individual customers. This should be used for the larger customizations in order to do the following:
- * Adapt business processes and add rules
- * Modify integrations with core systems
- * Add customer-specific extensions that need to reside inside the solution application model
- * Complete (custom) Integrations
- * Make (larger) UI customizations
+* **Runtime configuration** through [database setting objects](/refguide/custom-settings/#database-settings) or [constants](/refguide/constants/) when configuring for the needs of customer groups. This should be used for light configuration and personalization through developer-built flexibility, for the following purposes:
+ * Enable/disable business processes.
+ * Provide conditional access to capabilities, such as through feature toggles.
+ * Parameterize capabilities for groups of customers, such as through configurable thresholds.
+* **Design-time adaptation** for changing the application model to the needs of individual customers. This should be used for larger customizations in order to do the following:
+ * Adapt business processes and add rules.
+ * Modify integrations with core systems.
+ * Add customer-specific extensions that need to reside inside the solution application model.
+ * Complete (custom) Integrations.
+ * Make (larger) UI customizations.
-For some customizations, both approaches can be utilized, but Mendix recommends taking the following into account:
+For some customizations, both approaches can be used, but Mendix recommends taking the following into account:
* How easy is it to build and maintain?
* Is it easy to implement and upgrade afterwards?
* What is the impact on performance?
-Mendix recommends design-time model adaptation over "building Mendix in Mendix."
+Mendix recommends design-time model adaptation over building Mendix in Mendix.
### Design-Time Adaptation
-For design-time adaptations, Mendix recommends referencing [How to Set Up a Solution](/appstore/creating-content/sol-set-up/) and [How to Upgrade a Solution](/appstore/creating-content/sol-upgrade/) in order to create a dedicated app and Git repository per customer (including the partner that implements on behalf of the customer) and keeping these up to date. This allows for the following:
+For design-time adaptations, Mendix recommends referencing [How to Set Up a Solution](/appstore/creating-content/sol-set-up/) and [How to Upgrade a Solution](/appstore/creating-content/sol-upgrade/). These provide details on creating a dedicated app and Git repository for each customer, including for the partner that implements the solution on behalf of the customer. This allows for the following:
-* Full control of who can access the individual customer’s model instance via [app roles](/developerportal/general/app-roles/)
+* Full control over who can access the individual customer’s model instance via [app roles](/developerportal/general/app-roles/)
* Preventing access to [IP-protected](/appstore/creating-content/sol-ip-protection/) content and the development of the original solution template
* Using all [Mendix Portal collaboration features](/developerportal/general/)
* Data isolation per customer tenant by having dedicated environments (at least acceptance and production)
-The customer model instances will run with [IP protection](/appstore/creating-content/sol-ip-protection/) enabled, meaning that parts of the original solution model can be hidden. Once the solution is published with the protected solution models, this implementation hiding cannot be undone by the consumer of the solution model.
+The customer model instances run with [IP protection](/appstore/creating-content/sol-ip-protection/) enabled. This means that parts of the original solution model can be hidden. Once the solution is published with the protected solution models, the consumer of the solution model can no longer unhide the implementation.
{{< figure src="/attachments/appstore/create-content/create-solutions/sol-adapt/solution-deployment.png" alt="Development and deployment model for Solution Implementation" width="50%" class="no-border" >}}
### Customers Without Adaptation
-It may occur that not all of your customers require model adaptation, so they can run on an unmodified version of the original solution model. In this case, Mendix recommends distributing and deploying a deployment package (MDA), which also prevents inspection in the Mendix model and ensures seamless upgrades. This can be combined with flexible environments and/or a multi-tenancy setup.
+Not all customers might require model adaptation. This means they can run on an unmodified version of the original solution model. In this case, Mendix recommends distributing and deploying a deployment package (MDA), which also prevents inspection in the Mendix model and ensures seamless upgrades. This can be combined with [flexible environments](/developerportal/deploy/environments/#flexible-environments) and/or a multi-tenancy setup.
-If after going live it becomes necessary to adapt the model for a customer, a solution can be initialized. If right after initialization a database backup is restored to the newly created environment, no data loss should happen.
+If you need to adapt the model for a customer after it goes live, you can initialize a solution. If a database backup is restored to the newly created environment after initialization, no data is lost.
{{% alert color="info" %}}
Make sure to test this scenario before applying any customizations, since this only works when the application model is based on the same version of the solution.
@@ -84,51 +82,51 @@ Make sure to test this scenario before applying any customizations, since this o
### Combining Module Types
-An adaptable solution can exist of multiple core and adaptable modules. When creating a solution, it is important to make a distinction between the different module types and their purpose in the application model:
+An adaptable solution can include multiple core and adaptable modules. When creating a solution, it is important to make a distinction between the different module types and their purpose in the application model:
| Type | Contains | Implementation | Responsibility |
| --- | --- | --- | --- |
| [Solution modules](/refguide/module-settings/#solution-module) | Immutable common core with intellectual property and core logic | Hidden | Build team |
| [(Open) application modules](/refguide/module-settings/#app-module) | Adaptable parts of the app | Visible, can be changed | Shared between build and implementation teams |
-| [UI modules](/refguide/ui-resources-package/) | Contains theming | Shown, can be changed | Shared between build and implementation teams |
+| [UI modules](/refguide/ui-resources-package/) | Theming | Shown, can be changed | Shared between build and implementation teams |
| Customer-specific modules | Customer-specific additions | Visible | Implementation team |
-Solution modules are unique in the sense that it is not possible to see or alter their implementation details (for example, viewing the logic inside a microflow, changing the parameters, or editing the data model). They act as a "system" module for your solution.
+You cannot see or alter the implementation details of solution models. For example, you cannot view the logic inside a microflow, change the parameters, or edit the data model. Implementation details act as a system module for your solution.
However, documents can refer back and forth between solution and app modules. This allows for patterns with partial editability, abstract concepts, and an extensible front-end. To make things easy to maintain, it is a good practice to keep one adaptable module for each core module that is marked as a solution module. These modules will be tightly coupled, and should be considered as one module, so that the core module will have dependencies on the adaptable module, and vice versa.
Studio Pro enforces consistency during both development and implementation, and enables finding usages while protecting the implementation.
{{% alert color="info" %}}
-This is an exception to the cyclic dependency rule, in that a solution module may have an open module counterpart while they work together as one module.
-{{% /alert %}}
-{{% alert color="info" %}}
-Be sure to configure the [Solution](/refguide/app-settings/#solution) tab of **App Settings** to allow for distribution as an adaptable solution and for creating solution modules.
+* This is an exception to the cyclic dependency rule, in that a solution module may have an open module counterpart while they work together as one module.
+* Be sure to configure the [Solution](/refguide/app-settings/#solution) tab of **App Settings** to allow for distribution as an adaptable solution and for creating solution modules.
+
{{% /alert %}}
-### Designing the Interfaces
+### Designing Interfaces
-When designing the interfaces of your solutions, you should do the following:
+When designing the interfaces of your solutions, Mendix recommends the following:
-* Split your adaptable solution architecture into the [three main functional parts](/appstore/creating-content/sol-adapt/#three-parts)
-* Think about which parts of the shared core are reusable in other parts:
- * Define which shared logic should be reusable, and define entry points to the shared logic as APIs
- * Define which entities (data/state) are required in which parts of the functionality
-* Design APIs between the common core and extension modules, and consider making public only the parts that are explicitly required in other parts of your current architecture (meaning, design for today)
-* Design APIs for custom-specific modules, focus on current customer requests and their value, and focus on a minimum viable product (MVP) by keeping it small and simple
-* Iterate with customers to evolve the adaptability of the solution by evolving the architecture
- * Progressively, the architecture will emerge and become more complex as your solution becomes more successful, so re-architect when necessary
+* Split your adaptable solution architecture into the [three main functional parts](/appstore/creating-content/sol-adapt/#three-parts).
+* Think about which parts of the shared core are reusable in other parts.
+ * Define which shared logic should be reusable, and create entry points to the shared logic under the form of APIs.
+ * Define which entities (data/state) are required in which parts of the functionality.
+* Design APIs between the common core and extension modules, and consider making public only the parts that are explicitly required in other parts of your current architecture.
+* Design APIs for custom-specific modules, while focusing on current customer requests and their value.
+* Iterate with customers to make the solution more adaptable by evolving the architecture.
+ * The architecture becomes more complex as your solution becomes more successful, so re-architect when necessary.
+* Focus on creating a minimum viable product (MVP).
-### Applying IP Protection
+### Applying Intellectual Property (IP) Protection
-IP protection can be used to make parts of the application model and the common core immutable by customers. For practical guidance, see [How to Apply IP Protection](/appstore/creating-content/sol-ip-protection/).
+IP protection can be used to make parts of the application model and the common core immutable by customers. For practical guidance, see [Applying Intellectual Property Protection](/appstore/creating-content/sol-ip-protection/).
### Mendix Platform Version
-The [solution upgrade](/appstore/creating-content/sol-upgrade/) mechanism requires the application model to be of the same Mendix Platform version as the version of the solution upgrade package. Therefore, Mendix recommends the following:
+To [upgrade a solution](/appstore/creating-content/sol-upgrade/), the application's Mendix Platform version must match the version specified in the solution upgrade package. Therefore, Mendix recommends the following:
-* You should preferably publish a solution with the latest [MTS](/releasenotes/studio-pro/lts-mts/#mts) patch version to allow customer implementations to be upgraded to the latest patch version independently. This helps with decoupling of release cycles in case of a Mendix Platform bug or security update.
+* Publish a solution with the latest [MTS](/releasenotes/studio-pro/lts-mts/#mts) patch version. This allows customer implementations to be upgraded to the latest patch version independently. It also helps with decoupling release cycles in case of a Mendix Platform bug or security update.
* Never upgrade a solution implementation to a higher minor or major version on its own (for example, 9.18 to 9.20, or 9 to 10, respectively) when the solution is not upgraded.
This is the process for upgrading a solution to a higher minor or major version:
@@ -144,19 +142,19 @@ For more information, see [How to Deal with Platform Upgrades and Solution Versi
### Marketplace Modules
-Marketplace modules with data in the database included in the solution should always be upgraded through a solution release upgrade. They should never be upgraded in the customer implementation, as this can lead to loss of data.
+Marketplace modules which have data in the database included in the solution should always be upgraded through a solution release upgrade. They should never be upgraded in the customer implementation, as this can lead to loss of data.
-For example, a solution contains a module like the [Excel Importer](/appstore/modules/excel-importer/). If at any point the customer decides to update the module with a newer version rather than wait for an upgrade from the solution, the customer will run into merge conflicts later. As soon as they apply the upgrade from the solution vendor, the Team Server will be unable to properly identify the changes from both sides for the module. If this merge conflict is handled incorrectly, data loss will result.
+For example, a solution contains a module like the [Excel Importer](/appstore/modules/excel-importer/). If the customer decides to update the module with a newer version rather than wait for an upgrade from the solution, they will run into merge conflicts later. As soon as they apply the upgrade from the solution vendor, the Team Server will be unable to properly identify the changes from both sides for the module. If this merge conflict is handled incorrectly, data will be lost.
### Clean Coding
-Mendix recommends adhering to the [Mendix Best Practices for Development](/refguide/dev-best-practices/) and having clear coding conventions.
+Mendix recommends adhering to the [Mendix Best Practices for Development](/refguide/dev-best-practices/) and having clear coding conventions.
{{% alert color="warning" %}}
-For solutions that will be adapted at the model level, this is even more important.
+This is even more important for solutions that will be adapted at the model level.
{{% /alert %}}
-You should ensure the modifiable part of the model that will become editable is logically structured and well named and that the documents have a clear single purpose. This will make it easier to implement as well as to release newer versions and predict the impact of changes on existing solution implementations.
+You should ensure that the modifiable part of the model that will become editable is logically structured and well named, and that the documents have a clear single purpose. This will make it easier to implement, as well as to release newer versions and predict the impact of changes on existing solution implementations.
### Security
diff --git a/content/en/docs/appstore/create-content/create-solutions/sol-adapt/sol-ip-protection.md b/content/en/docs/appstore/create-content/create-solutions/sol-adapt/sol-ip-protection.md
index 4be214d2b5d..89945d02912 100644
--- a/content/en/docs/appstore/create-content/create-solutions/sol-adapt/sol-ip-protection.md
+++ b/content/en/docs/appstore/create-content/create-solutions/sol-adapt/sol-ip-protection.md
@@ -1,6 +1,6 @@
---
-title: "Apply Intellectual Property Protection"
-linktitle: "Apply IP Protection"
+title: "Applying Intellectual Property Protection"
+linktitle: "Applying Intellectual Property Protection"
url: /appstore/creating-content/sol-ip-protection/
weight: 2
description: "Protect intellectual property in solutions, app services, and connectors"
@@ -8,72 +8,74 @@ description: "Protect intellectual property in solutions, app services, and conn
## Introduction
-When selling solutions or components that are created in Mendix and the customer or partner will get access to the model, you as a publisher want to consider protecting the intellectual property (IP) contained within the model that makes up the content you are selling. In addition, you want to ensure that developers use the implementation as intended and protect any custom usage metering so that customers cannot accidentally (or intentionally) disable usage metering. Therefore, it is a good idea to consider applying at least some IP protection in your solutions and components.
+When selling solutions or components that are created in Mendix, and where the customer or partner gets access to the model, you should consider protecting the intellectual property (IP) of that content. In addition, you want to ensure that developers use the implementation as intended, and protect any custom usage metering so that customers cannot accidentally or intentionally disable it. Therefore, it is a good idea to consider applying at least some IP protection to your solutions and components.
-## Why IP Protection?
+## The Importance of IP Protection
-Reusable solutions, app services, connectors, and other modules contain IP in the form of app model content (for example, microflows) that is reusable and can be monetized. When you build a business around these types of sellable content, there is a risk associated with the loss of your IP. If customers copy your IP without compensating you as the publisher, then you lose out on part of your potential revenue.
+Reusable solutions, app services, connectors, and other modules contain IP in the form of app model content, such as microflows. This reusable content can be monetized. When you build a business around these types of sellable content, there is a risk associated with the loss of your IP. If customers copy your IP without compensating you as the publisher, then you lose out on part of your potential revenue.
-Therefore, when distributing such content, it is desirable to hide parts of the implementation from the eyes of your customers while making sure that the functionality can be used via well-designed APIs into your module (meaning, through explicitly defined microflows, nanoflows, and entities while all other documents and internal concerns are hidden).
+Therefore, when distributing such content, it is recommended to hide parts of the implementation from your customers, while making sure that the functionality can be used via well-designed APIs into your module. This means having explicitly defined microflows, nanoflows, and entities, while all other documents and internal concerns are hidden.
-You can also apply the concept of IP protection to protect your modules from being modified accidentally or intentionally. In this case, rather than protecting your IP for monetary reasons, you are protecting your IP to guarantee the functionality is used as intended. This will help streamline your maintenance and upgrade paths. This is relevant regardless of whether your application model is shared with external parties or not.
+You can also apply the concept of IP protection to protect your modules from being modified accidentally or intentionally. In this case, rather than protecting your IP for monetary reasons, you are protecting your IP to guarantee the functionality is used as intended. This helps streamline your maintenance and upgrade paths. This is relevant regardless of whether your application model is shared with external parties or not.
## Using a Legal Framework on Top of Technical Restrictions
-When using IP protection and [solution modules](/refguide/module-settings/#solution-module), the implementation is hidden in Studio Pro and from the Model SDK. This helps to protect your IP and prevent others from duplicating it. However, it does not prevent people from reverse-engineering how specific logic is built or analyzing the parts of the application that they do have access to. Therefore, make sure you have the right terms and conditions in place to protect your IP, which also allows you to act on any misuse of your application.
+When using IP protection and [solution modules](/refguide/module-settings/#solution-module), the implementation is hidden in Studio Pro and from the Model SDK. This helps protect your IP and prevent others from duplicating it. However, it does not prevent people from reverse-engineering how specific logic is built, or analyzing the parts of the application that they do have access to. Therefore, make sure you have the right terms and conditions in place to protect your IP, which also allows you to act on any misuse of your application.
-## What Should Be Protected?
+## Content that Should Be Protected
-To allow for [adaptability](/appstore/creating-content/sol-adapt/#three-parts), not all parts of a solution or component need to be protected. It is often desirable to protect the following:
+To allow for [adaptability](/appstore/creating-content/sol-adapt/#three-parts), not all parts of a solution or component need to be protected. Mendix recommend protecting the following:
-* **The core IP of the solution** – analyze the business logic (for example, scheduling or planning algorithms), complex data mappings, business rules, and decision logic that needs protection
-* **Custom usage metering** – ensure that the metering is tamper-proof (whether done accidentally or intentionally)
-* **Entitlement management** - control the use of your solution against a valid subscription
-* **Any part of the solution that the customer should never modify** – hide implementation details behind APIs to ensure customers or implementation teams focusing on extensions are not distracted by implementation details
+* **The core IP of the solution** – Analyze the business logic (for example, scheduling or planning algorithms), complex data mappings, business rules, and decision logic that needs protection.
+* **Custom usage metering** – Ensure that the metering is tamper-proof, whether done accidentally or intentionally.
+* **Entitlement management** - Control the use of your solution against a valid subscription.
+* **Any part of the solution that the customer should never modify** – Hide implementation details behind APIs to ensure customers or implementation teams focusing on extensions are not distracted by implementation details.
## Applying IP Protection Effectively
### Best Practices for Architecting
-* Identify your core IP
- * Think about which parts of the solution are most critical
- * Think about which parts of the solution will be adjusted by your customer (those parts cannot be protected)
-* Define the API
- * Identify the API of the IP-protected content
- * Think about extension needs, but keep it simple
- * Create simple interfaces with a limited feature set instead of over-engineering to support everything
- * Remember that APIs with lots of options are much harder to use, so simplicity is key
- * Limit API exposure, as it is easier to add more later than to retract interfaces
- * Apply proper naming and simple documentation for clarity
- * Consider the unhappy flow with the right validations and error handling
+* Identify your core IP:
+ * Think about which parts of the solution are most critical.
+ * Think about which parts of the solution will be adjusted by your customer. Those parts cannot be protected.
+* Define the API:
+ * Identify the API of the IP-protected content.
+ * Think about extension needs, but keep it simple.
+ * Create simple interfaces with a limited feature set instead of over-engineering to support everything.
+ * Refrain from defining APIs with lots of options, as they are much harder to use.
+ * Limit API exposure, as it is easier to add more later than to retract interfaces.
+ * Apply proper naming and simple documentation for clarity.
+ * Consider the unhappy flow with the right validations and error handling.
-For more details, see [How to Architect Adaptable Solutions](/appstore/creating-content/sol-architecting/).
+For more details, see [Architecting Adaptable Solutions](/appstore/creating-content/sol-architecting/).
### Benefits of Hiding Implementations {#implementation}
#### For the Publisher
-Mendix supports the hiding of module implementations as a means to protect your IP. As a publisher, you can control which parts of the app model are visible and editable, and which parts of the app model are hidden from your consumers. On top of the hidden model documents and elements, you can define an API to make it possible to reuse and extend the functionality in other parts of the app.
+Mendix supports the hiding of module implementations as a means of protecting your IP. As a publisher, you can control which parts of the app model are visible and editable, and which parts of the app model are hidden from your consumers.
-In this way, adaptable solutions can have a [common core](/appstore/creating-content/sol-architecting/#app-design) shared across all customers which is protected with an adaptable shell on top. The adaptable shell is customized for each customer, either by making model changes into the customizable core or by extending the app with entirely new modules. Both the customizations and extensions make use of the APIs of the common core.
+On top of the hidden model documents and elements, you can define an API to make it possible to reuse and extend the functionality in other parts of the app.
+
+This way, adaptable solutions can have a [common core](/appstore/creating-content/sol-architecting/#app-design) shared across all customers which is protected with an adaptable shell on top. The adaptable shell is customized for each customer, either by making model changes into the customizable core, or by extending the app with entirely new modules. Both the customizations and extensions make use of the APIs of the common core.
#### For the Consumer
Consumers of a solution with this kind of IP protection see only a well-designed API. This has the following results:
-* Simplified customization and clarification of how and where to extend, because the customer only needs to know those APIs, and it clarifies how and where to extend
-* Simplified usage of app services, connectors, and other modules, because the implementation details are hidden
-* Reduced maintenance efforts, because hidden content cannot be altered (this also makes in-place upgrades easier, as there is no need to check whether customizations have been applied)
+* Simplified customization and clarification of how and where to extend. The customer only needs to know those APIs, and it clarifies how and where to extend.
+* Simplified usage of app services, connectors, and other modules, because the implementation details are hidden.
+* Reduced maintenance efforts, because hidden content cannot be altered. This also makes in-place upgrades easier, as there is no need to check whether customizations have been applied.
### Protecting Component Types
#### Adaptable Solutions
-Adaptable solutions that will be customized by your customer, by a third-party implementation partner, or even by your own professional services teams can benefit from IP protection. By protecting the common core that is shared across customers, maintenance efforts are brought under control and the core is protected from accidental (or intentional) changes.
+Adaptable solutions that will be customized by your customer, by a third-party implementation partner, or even by your own professional services teams can benefit from IP protection. By protecting the common core that is shared across customers, maintenance efforts are kept under control, and the core is protected from accidental or intentional changes.
To protect your solutions, Mendix recommends these steps:
-1. Identify the shared [common core](/appstore/creating-content/sol-adapt/#three-parts) that will be unchanged across customers and protect it.
+1. Identify the shared [common core](/appstore/creating-content/sol-adapt/#three-parts) that will be unchanged across customers, and protect it.
2. Identify the parts that make up the flexible shell that customers might want to adapt.
3. Define clear APIs between the common core and the flexible shell. This ensures good architecture so that the core does not need to be adjusted and can be extended with limited effort.
@@ -81,7 +83,7 @@ Approach this iteratively, as it is often very hard to define these boundaries r
#### Full Solution Model
-Regardless of how the Mendix model is designed (with or without Solution Modules), implementation can always be hidden by sharing the MDA with the customer instead. This will allow for custom deployment, without being able to open the Mendix model.
+Regardless of how the Mendix model is designed (with or without Solution Modules), implementation can always be hidden by sharing the MDA with the customer instead. This allows for custom deployment, without being able to open the Mendix model.
#### App Services, Connectors, and Modules
@@ -91,10 +93,10 @@ Additionally, [hiding implementation details](#implementation) can simplify the
To protect your app services, connectors, and modules, follow these steps:
-1. Start by designing an API for your customers. Validate it with prospective customers (do not assume how they are going to use it).
+1. Start by designing an API for your customers. Validate it with prospective customers. Do not assume how they are going to use it.
2. Implement an agreed-upon subset of the desired API to cover around 80% of use cases.
3. Apply the “protect what’s behind the API” principle. Apply IP protection to relieve your customers of concerns about what is happening behind the API.
-4. When not applying IP protection to an entire module or set of modules, at least protect any modules that implement custom usage metering. This will protect against (accidental) tampering by customers.
+4. When not applying IP protection to an entire module or set of modules, at least protect any modules that implement custom usage metering. This will protect against accidental or intentional tampering by customers.
### Protecting Usage Metering {#metering}
@@ -102,23 +104,23 @@ To ensure customers do not accidentally or intentionally break usage metering, i
There are two common scenarios for custom usage metering:
-* **Tracking the assets managed in a solution** – when the asset is managed as an entity in the domain model, a gauge metric can be used to track the number of managed assets at regular intervals using a scheduled event
-* **Counting transactions handled by the solution through APIs or UIs** – on every invocation of a transaction, you can use an incrementing counter metric to track the total number of transactions handled over a period of time
+* **Tracking the assets managed in a solution** – When the asset is managed as an entity in the domain model, a gauge metric can be used to track the number of managed assets at regular intervals using a scheduled event.
+* **Counting transactions handled by the solution through APIs or UIs** – On every invocation of a transaction, you can use an incrementing counter metric to track the total number of transactions handled over a period of time.
These are the best practices for usage metering:
-* Verify that usage metering is "on the right side" and hidden behind the API
-* Make sure the usage metering does not depend on the specific invocation of an API
- * Relying on an after-startup microflow to start regular-interval usage metering is not a good idea, because it can be accidentally disabled
- * However, you can safely use an after-startup microflow if it is also used for functional purposes (for example, starting a custom request handler, or initializing a module when the module will not function without it)
-* Have a legal agreement for your solution or app service in place that includes a clause requiring the customer to ensure that any custom usage metering functions as intended
- * This means that where for some reason you cannot protect the metering implementation at the technical level, you are still covered at the legal level
+* Verify that usage metering is on the right side and hidden behind the API.
+* Make sure the usage metering does not depend on the specific invocation of an API.
+ Relying on an after-startup microflow to start regular-interval usage metering is not a good idea, because it can be accidentally disabled.
+ However, you can safely use an after-startup microflow if it is also used for functional purposes, for example, starting a custom request handler, or initializing a module when the module will not function without it.
+* Have a legal agreement for your solution or app service in place. This needs to include a clause requiring the customer to ensure that any custom usage metering functions as intended.
+ This means that where for some reason you cannot protect the metering implementation at the technical level, you are still covered at the legal level.
### Entitlement Management
-Applying IP protection will prevent the people consuming your solution from inspecting details of the model and copying the implementation thereof. On top of that, Mendix recommends considering implementing entitlement management.
+Applying IP protection prevents the people that consume your solution from inspecting details of the model and from copying the implementation. On top of that, Mendix recommends implementing entitlement management.
-Every implementation can have a cryptographically signed license key, which will allow the application to validate what entitlements are available for the implementation. This will prevent misuse and can enable features like the following:
+Every implementation can have a cryptographically signed license key, which will allow the application to validate what entitlements are available for the implementation. This prevents misuse and can enable features like the following:
* Free evaluation of the product on a *localhost*
* Freemium models using Free Apps on *.mxapps.io*
diff --git a/content/en/docs/appstore/create-content/create-widgets.md b/content/en/docs/appstore/create-content/create-widgets.md
index 33a8316bd78..b533d7cadc1 100644
--- a/content/en/docs/appstore/create-content/create-widgets.md
+++ b/content/en/docs/appstore/create-content/create-widgets.md
@@ -1,20 +1,20 @@
---
-title: "Create Widgets"
+title: "Creating Widgets"
url: /appstore/guidelines-creating-widgets/
description: "Describes guidelines for creating widgets in the Marketplace."
weight: 2
tags: ["marketplace", "content creation", "guidelines", "widgets"]
---
-## 1 Introduction
+## Introduction
-The guidelines to develop widgets submit them to the Marketplace as as follows:
+Follow these guidelines when developing widgets and submitting them to the Marketplace:
* The widget should be [pluggable](/howto/extensibility/create-a-pluggable-widget-one/).
-* When writing variable and function names, use lower camel case, for example, `mySecondVariable`.
+* When writing variable and function names, use lower camel case. Example: `mySecondVariable`.
* Add code comments.
* Use descriptive variable and function names in both XML and JavaScript.
* A function should contain at most 200 lines of code.
-* A function should only do one thing and do it properly.
+* A function should only do one thing, and do it properly.
* Use hooks and functional components over class components.
* Create test pages for mobile when content is made for mobile platforms.
diff --git a/content/en/docs/appstore/create-content/partner-program.md b/content/en/docs/appstore/create-content/partner-program.md
index adcc9260e0e..ebaf12a38cb 100644
--- a/content/en/docs/appstore/create-content/partner-program.md
+++ b/content/en/docs/appstore/create-content/partner-program.md
@@ -17,25 +17,25 @@ Whether you are an established ISV, an ambitious startup, or a pioneering indepe
In return, you will gain the following benefits:
-* Reach a global community of Mendix developers
-* Win new income streams
-* Develop brand awareness with target audiences
-* Drive demand for your services
-* Present a [partner icon](/appstore/component-details/#header) on the components you support
+* Reach a global community of Mendix developers.
+* Win new income streams.
+* Develop brand awareness with target audiences.
+* Drive demand for your services.
+* Present a [partner icon](/appstore/component-details/#header) on the components you support.
## Joining the Marketplace Program
The process is simple:
-1. Sign up as a [Mendix Component Partner](https://www.mendix.com/partners/become-a-partner/component-partner/)/.
+1. Sign up as a [Mendix Component Partner](https://www.mendix.com/partners/become-a-partner/component-partner/).
2. Design and build your content.
3. Edit your listing and submit it to the Marketplace for the [Partner](/appstore/marketplace-content-support/#category) support category.
-As a partner in the Mendix Marketplace, you can offer your components to customers all over the world who are looking for innovative ways to address their business challenges. You will be part of a powerful ecosystem that provides a wealth of resources and support to help you succeed.
+As a partner in the Mendix Marketplace, you can offer your components to worldwide customers who are looking for innovative ways to address their business challenges. You will be part of a powerful ecosystem that provides a wealth of resources and support to help you succeed.
-There are a few steps to publishing an offering. A partner interested in publishing its product (or products) on the Mendix Marketplace must meet certain criteria and must comply with some legal, compliance, technical, operational, and marketing requirements.
+There are a few steps to publishing an offering. A partner interested in publishing their products on the Mendix Marketplace must meet certain criteria and must comply with some legal, compliance, technical, operational, and marketing requirements.
-Currently, we are offering product listings with contact referrals for commercial content. There is currently no fee to publish an offering on the Mendix Marketplace.
+We are offering product listings with contact referrals for commercial content. There is no fee to publish an offering on the Mendix Marketplace.
## Read More
diff --git a/content/en/docs/appstore/create-content/upload-content/_index.md b/content/en/docs/appstore/create-content/upload-content/_index.md
index a3c69cd8b36..fabd9ea0720 100644
--- a/content/en/docs/appstore/create-content/upload-content/_index.md
+++ b/content/en/docs/appstore/create-content/upload-content/_index.md
@@ -1,5 +1,5 @@
---
-title: "Upload to the Marketplace"
+title: "Uploading to the Marketplace"
url: /appstore/submit-content/
weight: 6
description_list: true
@@ -16,24 +16,21 @@ aliases:
The Mendix Marketplace is driven by contributions from community members who share the connectors, modules, and apps they have built with the Mendix Platform.
-This how-to teaches you how to do the following:
-
-* Add new content and promotions to share in the Marketplace
-* Update existing Marketplace content
-
## Prerequisites
-Before starting this how-to, make sure you have reviewed the [Marketplace Overview](/appstore/overview/) and [How to Use Marketplace Content](/appstore/use-content/).
+Before starting this how-to, make sure you have completed the following prerequisites:
+
+* Familiarize yourself with [Marketplace Overview](/appstore/overview/) and [Using Marketplace Content](/appstore/use-content/).
## Adding New Marketplace Content {#adding}
-To get started, click **Add Content** on the Marketplace home screen. Follow the steps in the sections below to add and submit the content.
+To get started, click **Add Content** in the left pane of the Marketplace home screen. Follow the steps in these sections to add content.
{{% alert color="info" %}}
On each page of the upload flow, click one of the following buttons:
-* **Save Draft & Exit** to save the details you have entered so far as a draft (accessible via [My Drafts](/appstore/home-page/#my-drafts)) and exit the upload flow
-* **Next** to continue to the next page in the upload flow
+* **Save Draft** to save the details you have entered so far for the draft. You can access the draft via the [My Drafts](/appstore/home-page/#my-drafts) link in the top bar.
+* **Save & Continue** to go to the next page of the upload flow.
{{% /alert %}}
### General {#general}
@@ -48,22 +45,20 @@ Follow these steps to describe your content:
{{% alert color="warning" %}}You can only set the content type when creating the initial version of your content. You cannot change this setting after it is published.{{% /alert %}}
-2. Select the location **Visibility** where you want to publish your component:
+2. Select the **Visibility** of your component:
- * **Public Marketplace (all Mendix users)** – your component will be available to the Mendix community
- * This content will have to be reviewed and approved by Mendix before it is available
- * **Private Marketplace (your company only)** – your content will receive the **Private** label and be available only via your [Company Content](/appstore/home-page/#company-content) page
- * Selected private content of a content group can also be made available to [content group guests](/appstore/home-page/#guests) for download
- * This content will not be reviewed by Mendix
-
- {{% alert color="warning" %}}You can only set the location in the initial version of your content. You cannot change this setting by updating the Marketplace component later.{{% /alert %}}
+ * **Public Marketplace (all Mendix users)** – Your component will be available to the entire Mendix community.
+ * This content must be reviewed and approved by Mendix before it is available.
+ * **Private Marketplace (your company only)** – Your content will receive the **Private** label, and be available only via your [Company Content](/appstore/home-page/#company-content) page.
+ * Selected private content of a content group can also be made available to [content group guests](/appstore/home-page/#guests) for download.
+ * This content is not reviewed by Mendix.
+ {{% alert color="warning" %}}You can only set the visibility in the initial version of your content. You cannot change this setting by updating the Marketplace component later.{{% /alert %}}
-3. You can add one **Category** (up to three total) for your component. A category groups similar components or services that share characteristics, functions, or purposes. Categories make it easier for Marketplace users to find what they are looking for.
-4. Select a maximum of three tags for the **Industry** to indicate the sectors the component will operate.
-5. Enter a **Name** for your component.
-6. Enter a **Description** of your component.
+3. Add between one and three categories in the **Category** field. A category groups together similar components or services that share common characteristics, functions, or purposes. Categories make it easier for Marketplace users to find what they are looking for.
+4. Enter a **Name** for your component.
+5. Enter a **Description** of your component.
- {{% alert color="warning" %}}You can use rich text in the editor. However, using rich text at the beginning of the description is not recommended, as it will not get rendered properly. You should add a few lines of regular text before using rich text.{{% /alert %}}
+ {{% alert color="warning" %}} You can use rich text in the editor. However, using rich text at the beginning of the description is not recommended, as it will not get rendered properly. You should add a few lines of regular text before using rich text. {{% /alert %}}
#### Providing License Details {#license}
@@ -75,28 +70,31 @@ These are the open-source software license options available and their requireme
| | **Notes** | **Commercial use allowed?** | **Component code needs to be in public repo?** | **License text required with copyright info in code and distribution artifact?** | **Can modify?** (Mention modifications to code) | **Can consuming apps use without making their code public?** | **Notice files should be distributed with artifact?** | **Original component source code to be distributed with consuming app?** | **Can sub-license?** |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
-| [MIT](https://opensource.org/licenses/MIT) | Add a specific *license.txt* file in your artifacts (meaning, in the *.mpk*). | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} |
-| **BSD 2.0, 3.0** | | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} |
-| **Apache 1.0** | | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} |
-| [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0) | Add a specific *license.txt* file in your artifacts (meaning, in the *.mpk*). | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} |
-| **Creative Commons CC0 1.0 Universal (CC-0)** (Public Domain) | | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} |
+| [MIT](https://opensource.org/licenses/MIT) | Add a specific *license.txt* file in your artifacts, i.e. in the *.mpk* package. | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} |
+| **BSD 2.0, 3.0** | N/A | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} |
+| **Apache 1.0** | N/A | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} |
+| [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0) | Add a specific *license.txt* file in your artifacts, i.e. in the *.mpk* package. | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} |
+| **Creative Commons CC0 1.0 Universal (CC-0)** (Public Domain) | N/A | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="remove-circle-filled" color="red" >}} | {{< icon name="checkmark-circle-filled" color="green" >}} |
{{% alert color="info" %}}
-The [GNU General Public License (GPL), version 3](https://www.gnu.org/licenses/gpl-3.0.en.html) is not available to use, as everything licensed under GNU GPL is public. Its strong copyleft effect mandates that any modifications and derivative works, including consuming apps, must have their source code public.
+The [GNU General Public License (GPL), version 3](https://www.gnu.org/licenses/gpl-3.0.en.html) is not available to use, as everything licensed under GNU GPL is public.
+GNU GPL has a strong copyleft effect.
+Modification has a strong copyleft effect.
+All consuming apps should make their code public.
{{% /alert %}}
##### Proprietary Licenses {#proprietary-license}
-You can configure a proprietary license for your company’s content, which can be applied to multiple components and used by everyone within your organization.
+You can configure your own proprietary license for your company’s content. The license can be applied to multiple components, and it can be used by everyone within your organization.
-This license can be created for a new **Public Marketplace (all Mendix users)** component by requesting a new license and submitting it alongside the component. The license needs to be approved by Mendix after you have created and submitted it the first time. Once it is submitted for approval, you and the people within your organization can use it for other components.
+This license can be created for a new **Public Marketplace (all Mendix users)** component by requesting a new license and submitting it alongside the component. The license needs to be approved by Mendix after you have created and submitted it the first time. Once it has been submitted for approval, you and the people within your organization can also use it for other components.
Follow these steps to configure a proprietary license for a new public component:
1. Click **Request New License**.
-2. Add a **License Name**, which is the name that will be displayed on the [component details page](/appstore/component-details/).
+2. Add a **License Name**, which will be displayed on the [component details page](/appstore/component-details/).
3. Add a **License URL**, which should lead the user to a web page that lists the terms and conditions for using the component. Users can navigate to this web page by clicking the license name on the component details page.
-4. Add a **Reason** for the new license. This is for the purpose of the Mendix review only, and it will not be displayed on the component details page.
+4. Add a **Reason** for the new license. This is solely for Mendix review purposes, and will not be displayed on the component details page.
#### Generating New Leads {#lead-generation}
@@ -107,17 +105,17 @@ A lead is a potential sales contact that expresses interest in your product or s
When prospective customers are interested in your product, they can leave their contact information using the Marketplace product listing. This is done by clicking a call-to-action button and filling in a form.
-You can configure the name of your **Main call-to-action** button from the following choices:
+You can use one of these options as the name of your **Main call-to-action** button:
-* **Contact Us**, **Notify Me**, and **Request Demo** – requires the email address that will receive the customer information
+* **Contact Us**, **Notify Me**, and **Request Demo** – Requires the email address that will receive the customer information.
- {{% alert color="warning" %}}If you choose to add one of these buttons, customers can contact you directly. If you start talking with the customer, it is your responsibility to provide access to the product for that customer. Mendix is not involved in such customer interactions. {{% /alert %}}
+ {{% alert color="warning" %}}If you choose to add one of these buttons, customers can contact you directly. If you start talking with the customer, it is your responsibility to provide access to the product for them. Mendix is not involved in such customer interactions. {{% /alert %}}
-* **Download** – no lead routing is established, but customers can directly download your product.
+* **Download** – No lead routing is established, but customers can directly download your product.
-In the **How would you like to receive information on new leads?** field, you must specify the email address (or addresses) where notifications and information can be sent.
+In the **How would you like to receive information on new leads?** field, you must specify the email address or addresses where notifications and information can be sent.
-#### Finishing Up
+#### Adding an Icon
To finish the configuration on the **General** page, click **Upload Image** to upload a cover image for your component.
@@ -129,30 +127,30 @@ To finish the configuration on the **General** page, click **Upload Image** to u
If you are using **Solutions**, you will not see the option to select your content source. If you are using **Industry Template**, selecting a content source is optional.
{{% /alert %}}
-On the **Package** page, you can **Upload Source File**:
-
-* If you select **Manual upload**, follow the steps in the dialog box for uploading the package source file
- * When you are finished, click **Save**
-* If you select **GitHub URL**, follow the steps in the dialog box for copying the link of the release you want to import (for details, see the [Using a GitHub Repo](/appstore/guidelines-content-creators/#github) section in *Guidelines for Content Creators*).
- * To include the repo's *README.md* file on the component's [Documentation](#doc) tab, make sure you check the **Import Documentation** box
- * Click **OK** to finish
+1. Select one of the options for uploading the source file:
-If you selected **Widget** as the **Content Type** on the **General** page, you can optionally select **Compatibility** to test whether your component works with the React Client in Mendix Studio Pro 10.7 or higher. For details, see the [Widgets](/appstore/guidelines-content-creators/#github) section in *Mendix React Client*.
+* **Manual upload** – Follow the steps in the dialog box for uploading the package source file.
+ When you are finished, click **Save**.
+* **GitHub URL** – Follow the steps in the dialog box for copying the link of the release you want to import. For details, see the [Using a GitHub Repo](/appstore/guidelines-content-creators/#github) section in *Guidelines for Content Creators*.
+ To include the repo's *README.md* file on the component's [Documentation](#doc) tab, make sure you have selected the **Import Documentation** box.
+ When you are finished, click **OK**.
-Select the **Studio Pro Version** on which you built the content.
+2. Select the **Studio Pro Version** on which you built the content.
+
+3. Add a version for your component. If this is the first version of the component you are uploading, the number in the **Version** section will be automatically set to **1.0.0**.
-If this is the first version of the component you are uploading, the number in the **Version** section will be automatically set to **1.0.0**.
-
-Enter **Release Notes** for the component in the box provided describing what is new in that release.
+4. Enter **Release Notes** for the component in the box provided describing what is new in that release.
### Enable {#doc}
-On the **Enable** page, you can enter details on requirements and configuration for your component in the **Documentation**. Note that the documentation option is only available when the **Import Documentation** box has not been selected on the **Package** page.
+On the **Enable** page, in the **Documentation** section, you can enter details on requirements and configuration for your component.
+
+{{% alert color="info" %}} For GitHub uploads, the documentation option is only available if the **Import Documentation** box has not been selected on the **Package** page.
+{{% /alert %}}
-Follow the template for the recommended content:
+1. Follow the template for the recommended content:
* You must fill out the following sections in order to submit your component:
- * An extended **Description** of the component
* The **Typical usage scenario** for the component
* The **Features and limitations** of the component
* These sections are optional:
@@ -164,15 +162,15 @@ Follow the template for the recommended content:
The editor comes with a set of basic formatting tools, such as bold, bullet lists, and URL links.
-Click **Upload Screenshot** to select images of the component (especially for configuration) from your computer and upload them (this is required for submitting a new component):
+2. Click **Upload Screenshot** to upload images of the component from your computer. This is required for submitting a new component, and is especially important for configuration steps:
{{< figure src="/attachments/appstore/submit-content/enable.png" >}}
-You can optionally add a **YouTube URL** and a **Demo URL**.
+3. (Optional) Add a **YouTube URL** and a **Demo URL**.
### Publish {#publish}
-Finally, on the **Publish** page, you can review all the details of your component you entered so far and edit as necessary (via the **Edit** button per section) before publishing.
+Finally, on the **Publish** page, you can review all the details you entered so far, and edit them if necessary before publishing.
{{< figure src="/attachments/appstore/submit-content/publish.png" width="600" >}}
@@ -182,9 +180,11 @@ For details on the approval process, see [Governance Process](/appstore/submit-c
## Updating Existing Marketplace Content {#updating}
-After you publish a component in the Mendix Marketplace, your are responsible for keeping it updated on a regular cadence. These regular updates are important to maintain compatibility with the latest dependencies (especially Mendix Studio Pro), and are required for Mendix to ensure the quality of components in the Marketplace.
+After you publish a component in the Mendix Marketplace, it is your responsibility to make sure that the component is updated on a regular cadence. This is important to ensure compatibility with the latest versions of dependencies, especially Mendix Studio Pro. It is also required so Mendix can ensure the quality of components in the Marketplace.
-To meet these expectations, you must monitor, maintain, and evolve the component to improve its visibility on the Marketplace, build user loyalty, and maintain your company's reputation. If the component is not updated regularly, the listing will be reviewed for removal from public visibility.
+This means you need to monitor, maintain, and evolve the component, thus making sure that the Marketplace listing is more noticeable, that you can build user loyalty, and that you can maintain the good reputation of your company.
+
+If the component is not updated regularly, the Marketplace listing will be analyzed for removal from public visibility.
Mendix expects the following updates for components in the Platform, Community, and Premium [support categories](/appstore/marketplace-content-support/#category):
@@ -195,7 +195,8 @@ Mendix expects the following updates for components in the Platform, Community,
To update content that has already been published, follow these steps:
-1. Find the component by clicking one of the following:
+1. Find the component in one of the following sections:
+
* **My Content**
* **Company Content**
* **Content Group**
diff --git a/content/en/docs/appstore/create-content/upload-content/governance-process.md b/content/en/docs/appstore/create-content/upload-content/governance-process.md
index 3e05eaba56f..96f6a5cb435 100644
--- a/content/en/docs/appstore/create-content/upload-content/governance-process.md
+++ b/content/en/docs/appstore/create-content/upload-content/governance-process.md
@@ -9,23 +9,23 @@ description: "Describes the Mendix processes for approving and reviewing Marketp
All components that are to be listed in the [Public Marketplace](/appstore/submit-content/#public) are subject to an approval process to ensure the quality and accuracy of the listing and that the component meets the expectations of users. Component submissions are processed in a queue and reviewed on a first-come, first-served basis within five working days after submission.
{{% alert color="warning" %}}
-Mendix strongly recommends performing the checks below before you submit your component for approval. This will also speed up the approval process.
+Mendix strongly recommends performing the following checks before you submit your component for approval. This also speeds up the approval process.
{{% /alert %}}
### Checks
Mendix checks the following:
-* The licenses used in the uploaded *.mpk* files using the [Fossology](https://fossology.osuosl.org/repo/) tool
- * There should be no use of GPL, LGPL, or MPL licenses
- * For more details, see the [Providing License Details](/appstore/submit-content/#license) section above
-* For malware in the *.mpk* files using the [VirusTotal](https://www.virustotal.com/gui/home/upload) tool
-* For third-party vulnerabilities using the [Snyk](https://snyk.io/) tool
-* That the component can be used without errors in a specific Studio Pro version (if the component is a widget, module, connector, or an industry template)
-* That the documentation mentions all the details per the template (for example, dependencies, configuration, and how to use the component)
-* That the grammar, alignment, and spelling for the component's description and documentation is correct
-* That the logo is related to the component's functionality
-* That the screenshots are related to the configuration required to use the component in the end-user's app
+* The licenses used in the uploaded *.mpk* files, using the [Fossology](https://fossology.osuosl.org/repo/) tool .
+ There should be no use of GPL, LGPL, or MPL licenses.
+ For more details, see the [Providing License Details](/appstore/submit-content/#license) section in *Uploading to the Marketplace*.
+* For malware in the *.mpk* files, using the [VirusTotal](https://www.virustotal.com/gui/home/upload) tool.
+* For third-party vulnerabilities, using the [Snyk](https://snyk.io/) tool.
+* That the component can be used without errors in a specific Studio Pro version, if the component is a widget, a module, a connector, or an industry template.
+* That the documentation mentions all the details per the template, for example, dependencies, configuration, and how to use the component.
+* That the grammar, alignment, and spelling for the component's description and documentation are correct.
+* That the logo is related to the component's functionality.
+* That the screenshots are related to the configuration required to use the component in the end-user's app.
It may sometimes take a few iterations for a component to be approved, depending on the issues identified. To avoid a high number of necessary iterations, make sure you have followed the [Guidelines for Content Creators](/appstore/guidelines-content-creators/) and have performed the checks above before you submit a component for approval.
@@ -41,13 +41,14 @@ Review and approval by Mendix is required only for the first version of a public
As the Mendix Marketplace grows, it is important for users to be able to find up-to-date and relevant components. In order to reduce the likelihood that users find outdated or obsolete components, we review Marketplace content and evaluate for the following points:
-* Whether the component supports the versions of Studio Pro that Mendix supports (meaning, the current major version plus the two previous major versions – for more information, see [LTS, MTS, and Monthly Releases](/releasenotes/studio-pro/lts-mts/))
-* Whether the component has been updated recently (for example, a component was published in 2016 and has not been updated since)
-* Whether the component is being actively used, or if it has limited usage or very few downloads, reviews, or ratings
+* Whether the component supports the versions of Studio Pro that Mendix supports. This includes the current major version plus the two previous major versions.
+ For more information, see [LTS, MTS, and Monthly Releases](/releasenotes/studio-pro/lts-mts/)).
+* Whether the component has been updated recently.
+* Whether the component is being actively used, or if it has limited usage or very few downloads, reviews, or ratings.
-For a component that is outdated based on the above points, this is the review and remediation process:
+This is the review and remediation process for outdated components:
-1. Mendix sends a notification to the owner of the outdated component and the [Mendix Admin](/control-center/company-settings/), who then has to submit an update within 30 days in order for their component to remain active on the Marketplace. This update needs to be based on support for an active version of Studio Pro.
-2. Mendix sends two reminders during these 30 days (the first on the 15th day, and the second on the 25th day).
-3. If the component owner or Mendix Admin is unable to make the required update within the stipulated timeframe, Mendix unpublishes their component from the Marketplace. Unpublishing means the component is not listed on the Marketplace, but a copy of the component remains in the database.
+1. Mendix sends a notification to the owner of the outdated component and to the [Mendix Admin](/control-center/company-settings/). One of them then has to submit an update within 30 days in order for the component to remain active on the Marketplace. This update needs to be based on support for an active version of Studio Pro.
+2. Mendix sends two reminders during these 30 days: the first on the 15th day, and the second on the 25th day.
+3. If the component owner or Mendix Admin is unable to make the required update within the stipulated timeframe, Mendix unpublishes the component from the Marketplace. Unpublishing means the component is not listed on the Marketplace, but a copy of the component remains in the database.
4. If the owner or Mendix Admin wants to restore their unpublished component on the Marketplace, they make the required update and create a [Mendix Support](/support/submit-support-request/) request.
diff --git a/content/en/docs/appstore/overview/component-details.md b/content/en/docs/appstore/overview/component-details.md
index 49f1f0ea60f..67bbc0af626 100644
--- a/content/en/docs/appstore/overview/component-details.md
+++ b/content/en/docs/appstore/overview/component-details.md
@@ -8,25 +8,23 @@ description: "Presents information on the component details page."
---
## Introduction
-Clicking the tile of a [Marketplace](https://marketplace.mendix.com/) component brings you to its details page with the sections described below.
+Clicking the tile of a [Marketplace](https://marketplace.mendix.com/) component brings you to its details page with the sections described in this document.
-{{< figure src="/attachments/appstore/component-details/component-details.png" >}}
+{{< figure src="/attachments/appstore/component-details/marketplace_module.png">}}
-## Header {#header}
+## Component Header {#header}
-The header for a component presents the following details:
+The header for a component includes the following details:
* Labels (if there are any)
* **Partner**: If the header contains this label, it means that the component is partner-supported.
- * **Mendix**: If the header contains this label, it means that the component is platform-supported.
+ * **Platform Supported**: If the header contains this label, it means that the component is Mendix platform-supported.
* **Siemens**: If the header contains this label, it means that the component is Siemens-supported.
* **Recommended**: If the header contains this label, it means that the component meets your company's policies and guidelines, and therefore is recommended by your Mendix Admins.
* The name of the component
-* The review average (in stars) and the number of reviews
-* The number of times the component has been downloaded
-* **Save** – Click this to add the component to your [Saved Content](/appstore/home-page/#personal) list.
+* **Save** – Click this to add the component to your [Saved Content](/appstore/home-page/#personal) list.
* Depending on the content type:
* **Use in Studio Pro** for modules and widgets – Click this to copy the content ID so that you can [search for and use the component in Studio Pro](/appstore/use-content/#current-sp).
@@ -34,33 +32,39 @@ The header for a component presents the following details:
* **Download** for other content types – Click this to download the component.
* **Contact Us** – Click this to contact Mendix or the community supplier.
-The **Usage** section presents the following information (depending on the type of component):
+The **Publisher** section includes the following information, depending on the type of component:
-* The latest **Version** number of the component
-* The Studio Pro version that the component **Requires** to work
-* The type of [license](/appstore/submit-content/#license) for the component
+* The name of the company that created the component
+* The date when the component was first published
+* The latest version of the component
+* The review average, in stars, and the number of reviews
+* The number of times the component has been downloaded
-The **Publisher** section presents the name of the company who created the component as well as the **Date** when the component was first published.
+The **Requirements** section includes the following:
+
+* The Studio Pro version required for the component to work
+* The type of [license](/appstore/submit-content/#license) for the component
The **Support** section presents the category of support Mendix offers for the component (for more details, see the [Marketplace Content Support](/appstore/marketplace-content-support/) section below).
A **GitHub** link will take you to the GitHub source files of the component.
-## Tabs
+## Component Tabs
-The component details page also presents the following tabs:
+The component details page also includes the following tabs:
* **Overview** – This tab contains a description and screenshots of the component.
* **Documentation** – This tab includes details on typical use cases, features and limitations, dependencies, installation and configuration, frequently asked questions, and screenshots.
- * [Platform-supported components](/appstore/marketplace-content-support/#category) are documented according to content type or category in the [Marketplace Guide](/appstore/).
-* **Releases** – This tab lists all the versions of the component along with details like the **Framework version** and the **UUID**.
- * Each version can be downloaded by clicking **Download.**
+ * [Platform-supported components](/appstore/marketplace-content-support/#category) are documented in the [Marketplace Guide](/appstore/) according to content type or category.
+* **Releases** – This tab lists all the versions of the component along with details like the framework version and the UUID.
+ * Each version can be downloaded by clicking **Download**.
* If any version has the {{< icon name="react" color="blue" >}} REACT-CLIENT label next to it, it means this version is optimized for React Client applications. This label is only used for widgets.
* **Reviews** – This tab shows user reviews of the component.
* You can browse, sort by review date, and filter by ratings for insights on the component.
* You can select the **Only show my reviews** checkbox to check your own reviews.
* You can click **Write Review** to open a section where you can add text, rate the component, and submit the review.
- * Before you write a review, you can first read the **Tips for Sharing Your Review**, which appears on the right. You can now rate a component four or five stars without leaving a review. For three-, two-, and one-star ratings, a review is mandatory.
+ * Before you write a review, you can first read the **Tips for Sharing Your Review** on the right.
+ * You can now rate a component four or five stars without leaving a review. For three-, two-, and one-star ratings, a review is mandatory.
* You can find all your reviews on your [My Reviews](/appstore/home-page/#my-reviews) page in the Marketplace home page.
- * If you are a developer of the component, you can **Reply** to a review.
+ * If you are a developer of the component, you can reply to a review.
* **Developers** – This tab shows the names of the developers who most recently updated the component, with links to their [Mendix Profile](/community-tools/mendix-profile/).
diff --git a/content/en/docs/appstore/overview/marketplace-home-page.md b/content/en/docs/appstore/overview/marketplace-home-page.md
index 302465578dd..8a76d470529 100644
--- a/content/en/docs/appstore/overview/marketplace-home-page.md
+++ b/content/en/docs/appstore/overview/marketplace-home-page.md
@@ -19,8 +19,6 @@ For more information about content support, see [Marketplace Content Support](/a
## Introduction
-The [Mendix Marketplace](https://marketplace.mendix.com/) is a vibrant marketplace containing complete sample apps that can be used right away as well as various components (connectors, modules, widgets, and more) that can be used to build your apps more quickly. In the Mendix Marketplace, you can browse all the content, get what you need, and share the content you have created.
-
The Marketplace home page is your entry point to the various parts of the Mendix Marketplace. This document describes the different sections of the Marketplace home page.
The search box at the top of the page allows you to search for content. You can filter your search results using the fitlers on the right side of the page:
@@ -116,7 +114,7 @@ This page contains private content shared with you by other companies who have m
### Saved Content {#saved-components}
-This page presents the Marketplace content you have [saved](/appstore/component-details/#saved).
+This page presents the Marketplace content you have [saved](/appstore/component-details/).
Click the name of the component to go its [component details page](/appstore/component-details/).
diff --git a/content/en/docs/appstore/use-content/_index.md b/content/en/docs/appstore/use-content/_index.md
index fe95d093d1b..2cc8c6ddf26 100644
--- a/content/en/docs/appstore/use-content/_index.md
+++ b/content/en/docs/appstore/use-content/_index.md
@@ -1,5 +1,5 @@
---
-title: "Use Marketplace Content"
+title: "Using Marketplace Content"
url: /appstore/use-content/
weight: 3
description: "Covers the basics of how to access the Marketplace from Studio Pro and provides examples of how to add a widget and module to your app."
@@ -17,18 +17,13 @@ aliases:
This how-to covers the basics of accessing the Marketplace from Studio Pro and provides examples of how to add a widget and a module to your application.
-This how-to teaches you how to do the following:
-
-* Download content from the Marketplace via Studio Pro
-* Use content (for example, modules) downloaded from the Marketplace in Studio Pro
-
{{% alert color="warning" %}}
If you are using Studio Pro on a Mac with Parallels, see [this update](https://kb.parallels.com/112091#section7) for improving the loading time of Marketplace in Studio Pro.
{{% /alert %}}
## Installing Marketplace Content {#install}
-There are three ways to install a Marketplace component, which are described in the sections below.
+There are three ways to install a Marketplace component, which are described in the following sections.
### Finding and Downloading Content in Studio Pro {#downloading}
@@ -40,7 +35,7 @@ To download content in Studio Pro [9.19](/releasenotes/studio-pro/9.19/) and abo
2. Open the app in which you want to install the component from the Marketplace.
-3. To open the Marketplace in Studio Pro, you can either click the **View** menu in the top bar and select **Marketplace**, or you can click the Marketplace icon on the right side of the top bar
+3. To open the Marketplace in Studio Pro, you can either click the **View** menu in the top bar and select **Marketplace**, or you can click the Marketplace icon on the right side of the top bar.
{{< figure src="/attachments/appstore/use-content/toolbar.png" alt="Marketplace icon" class="no-border" >}}
@@ -49,20 +44,22 @@ To download content in Studio Pro [9.19](/releasenotes/studio-pro/9.19/) and abo
{{< figure src="/attachments/appstore/use-content/marketplace.png" alt="Search result for rating" class="no-border" >}}
4. You can explore Marketplace content in the following ways:
- * Use **Search in the Marketplace** to find the component that you want to download
- * You can paste the content ID here if you copied it via the [Use in Studio Pro button](/appstore/component-details/) in the web Marketplace
- * Filter via the **Categories** and **Subcategories** drop-down menus, which correspond to the [Marketplace content types](/appstore/overview/)
- * Filter for **All Content**, **My Company Content**, or **Platform-Supported Content**
+ * Use **Search in the Marketplace** to find the component that you want to download.
+ You can paste the content ID here if you copied it via the [Use in Studio Pro button](/appstore/component-details/) in the web Marketplace.
+ * Filter via the **Categories** and **Subcategories** drop-down menus, which correspond to the [Marketplace content types](/appstore/overview/).
+ * Filter for **All Content**, **My Company Content**, or **Platform-Supported Content**.
5. Select a component from the pane to see its details:
{{< figure src="/attachments/appstore/use-content/component-details.png" alt="Details of Blank App example component" class="no-border" >}}
- The details presented here correspond to what you see on the [component details page](/appstore/component-details/) in the online Mendix Marketplace.
+ The details presented here correspond to what you see on the [component details page](/appstore/component-details/) in the online Marketplace.
-6. Click **Download** to download the component. The correct version of the component that is compatible with your Studio Pro version is integrated directly into your application (for widgets, version compatibility is not applicable). By default, the highest correct version of the component is downloaded. If you want to download an older component version, go to the **Releases** tab and click **Download** for the desired version.
+6. Click **Download** to download the component.
+ The correct version of the component that is compatible with your Studio Pro version is integrated directly into your application. By default, the highest correct version of the component is downloaded. If you want to download an older component version, go to the **Releases** tab and click **Download** for the desired version.
+ Version compatibility is not applicable to widgets.
-7. Depending on whether the component is a widget, a module, an [extension](/appstore/modules/#introduction), (which is a special type of module), or an app, go to one of the sections below:
+7. Depending on the type of component, go to one of these sections:
* [Widgets](#widgets)
* [Modules](#modules)
@@ -79,15 +76,17 @@ If you download a module, the **Import Module** dialog box opens, where you shou
1. Select one of these options:
- * **Add as a new module** (default option when the module is downloaded to your app for the first time ) – if you select this option, new entities and attributes are created in your app.
+ * **Add as a new module** (default option when the module is downloaded to your app for the first time ) – If you select this option, new entities and attributes are created in your app.
- * **Replace existing module** (default option when the module already exists in your app) – if you select this option, you need to specify which **Module to replace**
+ * **Replace existing module** (default option when the module already exists in your app) – If you select this option, you need to specify which **Module to replace**
- {{% alert color="warning" %}}If you have made any changes to the existing module, selecting the **Replace existing module** option will replace all the changes that you made (for example, your renamed entities, attributes, and associations as well as their respective tables and columns represented in the database will all be replaced). Your user data will stay if you have not changed entities, attributes, or associations. If you have changed data types, your user data can be influenced as well. For more information, see [Attribute Type Migration](/refguide/attributes-type-migration/).{{% /alert %}}
+ {{% alert color="warning" %}}If you have made any changes to the existing module, selecting the **Replace existing module** option replaces all the changes that you made. For example, your renamed entities, attributes, and associations, as well as their respective tables and columns represented in the database will all be replaced. If you have changed data types, your user data can be influenced as well. User data will not be changed, though, if you have not changed entities, attributes, or associations. For more information, see [Attribute Type Migration](/refguide/attributes-type-migration/).{{% /alert %}}
2. Click **Import**.
-3. Wait until a pop-up window states that the module was successfully imported. Click **OK**. You can find the imported module in the **App Explorer**.
+3. Wait until a pop-up window states that the module was successfully imported, then click **OK**.
+
+You can find the imported module in the **App Explorer**.
##### Extensions {#extensions}
@@ -95,9 +94,10 @@ If you download an [extension](/appstore/modules/#introduction), a warning dialo
* If you trust the extension, click **Trust module and enable extension**.
-* If you decide to not trust the extension, you will get asked whether or not to trust the extension every time you reload the application.
+* If you decide to not trust the extension, you are asked whether or not to trust the extension every time you reload the application.
-Click **OK** in the confirmation pop-up window. Your extension is now installed and is ready to use. Depending on the extension that you have installed, the functionality appears in a certain location of your app. Read the extension-specific documentation to get more information on how to use it.
+Click **OK** in the confirmation pop-up window. Your extension is now installed and ready to use.
+Depending on the extension that you have installed, the functionality appears in a certain location of your app. Read the extension-specific documentation to get more information on how to use it.
If you do not want to trust the extension and would prefer to remove the extension altogether, you can remove the add-on module that was added.
@@ -107,23 +107,29 @@ If you do not want to trust the extension and would prefer to remove the extensi
If you download an app, the **Download Marketplace App** dialog box opens, where you should perform the following steps:
-1. Select where the app should be stored: **New Mendix Team Server**, **Existing Mendix Team Server**, or **Locally on disk**.
-2. Configure the necessary settings based on your storage choice.
-3. Click **OK**.
+1. Select where the app should be stored:
- After the app is downloaded, it opens automatically in Studio Pro.
+ * **New Mendix Team Server**
+ * **Existing Mendix Team Server**
+ * **Locally on disk**
-#### For Studio Pro 9.18 and Below
+2. Configure the necessary settings based on your storage choice.
+3. Click **OK**.
+ After the app is downloaded, it opens automatically in Studio Pro.
+
+#### For Studio Pro 9.18 and Above
-To download content in Studio Pro [9.18](/releasenotes/studio-pro/9.18/) and below, follow these steps:
+To download content in Studio Pro [9.18](/releasenotes/studio-pro/9.18/) and above, follow these steps:
1. Open Studio Pro and sign in with your Mendix credentials.
2. Open the app in which you want to install the component from the Marketplace.
3. Click the Marketplace icon in the top menu bar to open it in Studio Pro. The Marketplace opens within Studio Pro. The **Categories** menu item on the left side gives an overview of which types of content are available.
-4. Use the **Search** bar to find the component that you want to download. Note that results for Marketplace content searches within Studio Pro may differ from those in the online [Marketplace](/appstore/overview/) due to synchronization issue.
-5. Click the component (or the **Read more** button on the right side) to show the details of the component.
-6. Click **Download** to download the component. The correct version of the component that is compatible with your Studio Pro version is integrated directly into your application (for widgets, version compatibility is not applicable). By default, the highest correct version of the component is downloaded. If you want to download an older component version, go to the **Releases** tab and click **Download** for the desired version.
-7. Depending on whether the component is a widget, a module, or an app, go to one of the sections above:
+4. Use the **Search** bar to find the component that you want to download. Note that results for Marketplace content searches within Studio Pro may differ from those in the online [Marketplace](/appstore/overview/) due to a synchronization issue.
+5. Click the component or the **Read more** button on the right side to show the details of the component.
+6. Click **Download** to download the component.
+ The correct version of the component that is compatible with your Studio Pro version is integrated directly into your application. By default, the highest correct version of the component is downloaded. If you want to download an older component version, go to the **Releases** tab and click **Download** for the desired version.
+ Version compatibility is not applicable to widgets.
+7. Depending on the type of component, go to one of these sections:
* [Widgets](#widgets)
* [Modules](#modules)
@@ -131,13 +137,13 @@ To download content in Studio Pro [9.18](/releasenotes/studio-pro/9.18/) and bel
### Importing Content from Studio Pro's App Explorer {#import}
-{{% alert color="info" %}}This procedure works for [modules](/appstore/modules/) (including [add-on and solution modules](/refguide/module-settings/#module-type)).{{% /alert %}}
+{{% alert color="info" %}}This procedure is applicable to [modules](/appstore/modules/), including [add-on and solution modules](/refguide/module-settings/#module-type).{{% /alert %}}
To import content downloaded from the online Mendix Marketplace into Studio Pro, follow these steps:
1. Go to the [Marketplace](https://marketplace.mendix.com/) and sign in with your Mendix credentials.
-2. Search in the online Marketplace for the component you want to download and open the [component details page](/appstore/component-details/).
-3. Check **Usage** > **Version** to see the required Studio Pro version for the component. Do not download a component that requires a higher version than the one you are using.
+2. Search in the online Marketplace for the component you want to download, and open the [component details page](/appstore/component-details/).
+3. Access **Usage**, then **Version** to see the required Studio Pro version for the component. Do not download a component that requires a higher version than the one you are using.
4. Go to the **Releases** tab and **Download** the desired version. Mendix recommends using the latest version of the component if possible.
5. In the **App Explorer**, right-click the app, then click **Import module package**, and select the component you downloaded:
@@ -147,13 +153,13 @@ To import content downloaded from the online Mendix Marketplace into Studio Pro,
6. In the **Import Module** dialog box, select one of these options:
- * **Add as a new module** (default option when the module is downloaded to your app for the first time ) – if you select this option, new entities and attributes are created in your app
- * **Replace existing module** (default option when the module already exists in your app) – if you select this option, you need to specify which **Module to replace**
+ * **Add as a new module** (default option when the module is downloaded to your app for the first time ) – If you select this option, new entities and attributes are created in your app.
+ * **Replace existing module** (default option when the module already exists in your app) – If you select this option, you need to specify which **Module to replace**.
- {{% alert color="warning" %}}If you have made any changes to the existing module, selecting the **Replace existing module** option will replace all the changes that you made (for example, your renamed entities, attributes, and associations as well as their respective tables and columns represented in the database will all be replaced). Your user data will stay if you have not changed entities, attributes, or associations. If you have changed data types, your user data can be influenced as well. For more information, see [Attribute Type Migration](/refguide/attributes-type-migration/).{{% /alert %}}
+ {{% alert color="warning" %}}If you have made any changes to the existing module, selecting the **Replace existing module** option replaces all the changes that you made. For example, your renamed entities, attributes, and associations, as well as their respective tables and columns represented in the database will all be replaced. If you have changed data types, your user data can be influenced as well. User data will not be changed, though, if you have not changed entities, attributes, or associations. For more information, see [Attribute Type Migration](/refguide/attributes-type-migration/).{{% /alert %}}
7. Click **Import**.
-8. Wait until a pop-up window states that the module was successfully imported. Click **OK**.
+8. Wait until a pop-up window states that the module was successfully imported, then click **OK**.
You can find the imported module in the **App Explorer**.
@@ -169,8 +175,8 @@ To manually add content downloaded from the online Mendix Marketplace into Studi
6. Open the app in which you want to install the Marketplace component.
7. On the menu bar, click **App** > **Show App Directory in Explorer**. The app directory opens.
8. Add the component into the app directory as follows:
- * If it is a widget, add it into the **widgets** folder
- * If it is an *.mxmodule* file, add it into the **modules** folder (you need to create this folder if it does not already exist)
+ * If it is a widget, add it to the **widgets** folder.
+ * If it is an *.mxmodule* file, add it to the **modules** folder. You need to create this folder if it does not already exist.
9. On the menu bar, click **App** > **Synchronize App Directory**.
10. Wait until the synchronization is finished.
@@ -189,7 +195,7 @@ After you [install](#install) the widget from the Marketplace in your app, there
To add a widget from the **Toolbox**, follow these steps:
1. Open the page where you want to add the widget.
-2. In the **Toolbox**, search for the name of the widget (for example, *Rating* to find the widget):
+2. In the **Toolbox**, search for the name of the widget.
{{< figure src="/attachments/appstore/use-content/toolbox-rating.png" alt="Rating widget found in the toolbox" class="no-border" >}}
@@ -197,16 +203,18 @@ To add a widget from the **Toolbox**, follow these steps:
To add a widget using the **Add widget** option from the toolbar, follow these steps:
-1. Click **Add widget** on the toolbar on the page where you want to add the widget. The **Select Widget** dialog box opens.
+1. Click **Add widget** on the toolbar on the page where you want to add the widget.
+ The **Select Widget** dialog box opens.
{{< figure src="/attachments/appstore/use-content/add-widget.png" alt="Add widget" class="no-border" >}}
-2. In the **Filter** bar, enter the name of the widget, for example *Rating*, to find the widget.
+2. In the **Filter** bar, enter the name of the widget.
{{< figure src="/attachments/appstore/use-content/select-widget.png" alt="Rating widget highlighted in Select Widget dialog box" class="no-border" >}}
-3. Click the widget and then click **Select**.
-4. In the page, click where you want to drop the widget. The widget is added to the location where the mouse pointer is.
+3. Click the widget, then click **Select**.
+4. On the page, click where you want to drop the widget.
+ The widget is added to the location where the mouse pointer is.
{{< figure src="/attachments/appstore/use-content/widget-dropped-in-page.png" alt="Rating widget in the page" class="no-border" >}}
@@ -216,15 +224,15 @@ To update the widget in your app to a newer version, go to the Marketplace to do
##### Maintaining Added Translations in a Widget to Update
-In the scenario where you have an app with multiple languages in which you need to update an imported Marketplace widget that only comes with one language and where you have manually added translations for the additional languages you need, you can maintain the additional translations by following these steps:
+If you have an app with multiple languages in which you need to update an imported Marketplace widget that only comes with one language, and where you have manually added translations for the additional languages you need, you can maintain the additional translations by following these steps:
1. Maintain the translations for the widget by [exporting them to Excel](/refguide/batch-translate/#export).
-2. Update the widget via the steps described above.
+2. Update the widget via the steps described in the previous section.
3. [Import](/refguide/batch-translate/#import) the maintained translations from the Excel.
#### Configuring the Widget
-After you place the widget in your page, some new errors can appear in the [Errors](/refguide/errors-pane/) pane. That is because you still need to configure the widget. In this procedure, the Ratings widget is used as an example.
+After you place the widget on your page, some new errors can appear in the [Errors](/refguide/errors-pane/) pane. That is because you still need to configure the widget. In this procedure, the **Ratings** widget is used as an example.
To configure the widget, follow these steps:
@@ -232,7 +240,8 @@ To configure the widget, follow these steps:
{{< figure src="/attachments/appstore/use-content/widget-errors.png" alt="Errors pane" class="no-border" >}}
-2. In the page, double-click the Rating widget. The **Edit Rating** dialog box opens and the **Attribute** field shows **(none)** – this means that no attribute is assigned, which causes the error.
+2. On the page, double-click the **Rating** widget.
+ The **Edit Rating** dialog box opens, and the **Attribute** field shows **(none)**. This means that no attribute is assigned, which causes the error.
{{< figure src="/attachments/appstore/use-content/edit-rating.png" alt="Edit Rating dialog box" class="no-border" >}}
@@ -240,7 +249,8 @@ To configure the widget, follow these steps:
{{< figure src="/attachments/appstore/use-content/select-attribute.png" alt="ProductRating selected in Select Attribute dialog box" class="no-border" >}}
-4. In the **Edit Rating** dialog box, click **OK**. The error in the **Errors** pane disappears.
+4. In the **Edit Rating** dialog box, click **OK**.
+ The error in the **Errors** pane disappears.
### Using a Module {#module}
@@ -264,10 +274,10 @@ To update the module in your app to a newer version, follow these steps:
##### Maintaining Added Translations in a Module to Update
-In the scenario where you have an app with multiple languages in which you need to update an imported Marketplace module that only comes with one language and where you have manually added translations for the additional languages you need, you can maintain the additional translations by following these steps:
+If you have an app with multiple languages in which you need to update an imported Marketplace module that only comes with one language, and where you have manually added translations for the additional languages you need, you can maintain the additional translations by following these steps:
1. Maintain the translations for the module by [exporting them to Excel](/refguide/batch-translate/#export).
-2. Update the module via the steps described above.
+2. Update the module via the steps described in the previous section.
3. [Import](/refguide/batch-translate/#import) the maintained translations from the Excel.
#### Configuring the Module
@@ -278,7 +288,7 @@ Keep in mind that some modules you can download may come with their own user rol
### Using a Starter App
-Downloading a starter app (via **Create New App**) creates a new app structure in the storage location that you select. After you click **Download**, a window will appear where you can specify how the app should be created.
+Downloading a starter app via **Create New App** creates a new app structure in the storage location that you select. After you click **Download**, a window is displayed, allowing you to specify how the app should be created.
{{% alert color="info" %}}
You cannot create a new app in an existing repository that is not empty.
@@ -288,17 +298,17 @@ You cannot create a new app in an existing repository that is not empty.
To remove a widget from your app, follow these steps:
-1. In Studio Pro, go to **App** > **Show App Directory in Explorer** on the menu bar to open the app directory.
+1. In Studio Pro, go to **App**, then to **Show App Directory in Explorer** on the menu bar to open the app directory.
2. Go to the **widgets** folder.
3. Remove the *.mpk* file for the widget.
-4. In Studio Pro, go to **App** > **Synchronize App Directory**.
+4. In Studio Pro, go to **App**, then to **Synchronize App Directory**.
To remove a module and user data from your app, follow these steps:
1. In the **App Explorer**, find the module that you want to delete.
-2. Right-click the module and select **Delete** from the pop-up menu. A warning pop-up window opens.
+2. Right-click the module and select **Delete** from the pop-up menu. A warning pop-up window is displayed.
- {{% alert color="warning" %}} Once you delete a module, all your user data will be lost – even if you later install the module again. If you want to replace the existing module with a different version, do not delete the module – [update the module](#update-module) instead.{{% /alert %}}
+ {{% alert color="warning" %}} Once you delete a module, all your user data is lost, even if you later install the module again. If you want to replace the existing module with a different version, do not delete the module, but [update](#update-module) it instead.{{% /alert %}}
3. When you are sure that you want to delete the module and existing user data, click **Delete module and user data**.
diff --git a/content/en/docs/appstore/use-content/marketplace-content-support.md b/content/en/docs/appstore/use-content/marketplace-content-support.md
index d7f937c5e55..3ea2270881b 100644
--- a/content/en/docs/appstore/use-content/marketplace-content-support.md
+++ b/content/en/docs/appstore/use-content/marketplace-content-support.md
@@ -14,7 +14,7 @@ aliases:
## Introduction
-Support for Marketplace content is determined by the content support category and the service level agreement (SLA) the user possesses.
+Support for Marketplace content is determined by the user's content support category and service level agreement (SLA).
The content support category for a component is indicated by the label on the [header](/appstore/component-details/#header) in its component details page. The label can be **Platform Supported**, **Partner Supported**, or **Siemens Supported**. If there is no label indicating the content support category, then the component is community-supported.
@@ -22,21 +22,21 @@ The content support category for a component is indicated by the label on the [h
## Content Support Categories {#category}
-Support for Marketplace content is determined by the content support category and the service level agreement (SLA) the user possesses. We distinguish the following content support categories:
+These are the content support categories offered by Mendix:
| Category | Description |
| -------------- | ------------------------------------------------------------ |
-| **Platform Supported** | Mendix supports all the content in this category as-is when you are equipped with an SLA (**Platform**, **Standard**, or **Premium**) with Mendix. Content in this category is proactively incorporated into Mendix R&D test cycles as part of our platform release management. Please note that this category replaces the former **Extended** category, which has been deprecated. |
+| **Platform Supported** | Mendix supports all the content in this category as-is when you are equipped with an SLA (**Platform**, **Standard**, or **Premium**) with Mendix. Content in this category is proactively incorporated into Mendix R&D test cycles as part of our platform release management. Note that this category replaces the former **Extended** category, which has been deprecated. |
| **Deprecated** | The content in this category is considered end-of-life and will be dropped to the **Community support** status in the next major release of Mendix. Content is provided as-is by Mendix R&D, and support depends on the severity of the reported issue and the effort required to resolve it. |
| **Community Supported** | Content is provided as-is by members of the Mendix community, and support depends on the availability and effort of the owner. Mendix Support is not responsible for any content in this category, even if the content is owned by developers who work or previously worked at Mendix. |
-| **Partner Supported** | The content in this category is provided and supported by a partner. The partner supports this content as-is when you are equipped with an SLA with the partner. For more information, see [Mendix Component Partner Program](/appstore/partner-program/). |
-| **Siemens Supported** | The content in this category is provided and supported by the Siemens team. Siemens supports this content as-is when you are equipped with an SLA with Siemens. |
+| **Partner Supported** | The content in this category is provided and supported by a partner. The partner supports this content as-is when you have an SLA with the partner. For more information, see [Mendix Component Partner Program](/appstore/partner-program/). |
+| **Siemens Supported** | The content in this category is provided and supported by the Siemens team. Siemens supports this content as-is when you have an SLA with Siemens. |
## Feedback Process Details
We are always curious about and grateful for your feedback. The way you communicate your feedback to us depends on the support category of the content.
-### Platform Category
+### Platform Supported
The applicable level of service for Mendix-supported Marketplace content is equal to the Mendix SLA you have acquired. In other words, the same SLA conditions apply to support on Marketplace content. This means that equal response and resolve times are applicable, and the standard support process using the [Mendix Support Portal](https://support.mendix.com) has to be followed.
@@ -44,22 +44,23 @@ The applicable level of service for Mendix-supported Marketplace content is equa
Content in this support category is supported as-is. If you change the content of the module, the module will no longer be platform-supported.
{{% /alert %}}
-### Deprecated Category {#deprecated}
+### Deprecated {#deprecated}
Mendix moves platform-supported content into this category when the content is considered end-of-life. These decisions factor in popularity, the availability of improved alternatives, and industry standards.
{{% alert color="info" %}}
-Support for content in this category is limited and is decided by Mendix on a case-by-case basis. You can still follow the standard support process using the [Mendix Support Portal](https://support.mendix.com). However, the Mendix SLA no longer applies.
+Support for content in this category is limited, and is decided by Mendix on a case-by-case basis. You can still follow the standard support process using the [Mendix Support Portal](https://support.mendix.com). However, the Mendix SLA no longer applies.
{{% /alert %}}
-### Community Category {#community-category}
+### Community Supported {#community-category}
-Support on content in this category is up to the user or organization providing the content. Mendix recommends contacting the owner of the content in case of questions or issues via the following methods:
+Support for content in this category is up to the user or the organization providing the content. Mendix recommends contacting the owner of the content in case of questions or issues. You can use one of the following methods:
-* Open an issue on the GitHub repository associated with the content (for details on GitHub issues, see [Mastering Issues](https://guides.github.com/features/issues/))
-* Contact the owner of the content via the contact details available on the Marketplace component's detail pages
-* Ask a question in the [Mendix Community](https://community.mendix.com/)
-* Contribute
+* Open an issue on the GitHub repository associated with the content.
+ For details on GitHub issues, see [Mastering Issues](https://guides.github.com/features/issues/).
+* Contact the owner of the content via the contact details available on the Marketplace component's detail pages.
+* Ask a question in the [Mendix Community](https://community.mendix.com/).
+* Contribute.
{{% alert color="warning" %}}
Mendix Support is not responsible for any community-supported content, since every Mendix user can create and publish community-supported content in the Mendix Marketplace, including developers who work or previously worked at Mendix.
@@ -67,7 +68,7 @@ Mendix Support is not responsible for any community-supported content, since eve
The level of support for the community-supported content totally depends on the availability and effort of the content developer and the Mendix community.
{{% /alert %}}
-### Partner Category
+### Partner Supported
Partner-supported content is created and maintained by partners as part of the [Mendix Component Partner program](/appstore/partner-program/). Partners in the program commit to providing support to paying customers under an SLA (meaning, under terms specified by the partner). Customers can rely on this SLA for support from the partner if something goes wrong. A partner-supported Marketplace [component details page](/appstore/component-details/) contains a reference to the partner's support portal or the partner's support contact email.
diff --git a/static/attachments/appstore/component-details/marketplace_module.png b/static/attachments/appstore/component-details/marketplace_module.png
new file mode 100644
index 00000000000..9cf084513e7
Binary files /dev/null and b/static/attachments/appstore/component-details/marketplace_module.png differ
diff --git a/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/microflow-action.png b/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/microflow-action.png
index 0c714ce619c..b52393c7570 100644
Binary files a/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/microflow-action.png and b/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/microflow-action.png differ
diff --git a/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-change-value.png b/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-change-value.png
index ae5ad27cb46..9e8ff571c33 100644
Binary files a/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-change-value.png and b/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-change-value.png differ
diff --git a/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-new-constants.png b/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-new-constants.png
index 887f21bb57e..686e0c99c32 100644
Binary files a/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-new-constants.png and b/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-new-constants.png differ
diff --git a/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-select-constant.png b/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-select-constant.png
index 3f210e61fb0..cafbf3246e8 100644
Binary files a/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-select-constant.png and b/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-select-constant.png differ
diff --git a/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-settings.png b/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-settings.png
index 3573a3bd37b..4ac469b8fcd 100644
Binary files a/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-settings.png and b/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-settings.png differ
diff --git a/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-value.png b/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-value.png
index b1240f617af..53f2028c884 100644
Binary files a/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-value.png and b/static/attachments/appstore/create-content/create-connectors/connector-guide-best-practices/simple-config-value.png differ