From 47364952db17bdf95b835d478aaa56cce58ab910 Mon Sep 17 00:00:00 2001 From: Sharad Regoti Date: Mon, 6 Jan 2025 14:37:32 +0530 Subject: [PATCH 1/3] Initial Commit --- tyk-docs/config.toml | 2 + tyk-docs/content/developer-support/faq.md | 36 + .../api-access.md} | 335 +- tyk-docs/content/portal/customization.md | 3097 +++++++++++++++++ tyk-docs/content/portal/developers.md | 367 ++ tyk-docs/content/portal/install.md | 1852 ++++++++++ tyk-docs/content/portal/overview.md | 417 +++ .../enable-sso.md => portal/settings.md} | 101 +- .../portal-1.9.0-list-of-endpoints.md | 235 -- .../deploy/bootstrapping-portal.md | 92 - .../deploy/install-tyk-enterprise-portal.md | 79 - .../install-portal-using-docker-compose.md | 285 -- .../install-portal-using-docker.md | 294 -- .../install-portal-using-helm.md | 75 - .../install-portal-using-new-helm.md | 66 - .../install-portal-using-rpm.md | 118 - .../install-tyk-enterprise-portal/overview.md | 34 - .../create-api-product-and-plan.md | 73 - .../create-orgs-and-catalogs.md | 85 - .../customize-products-and-plans.md | 63 - .../getting-started/customize-sign-up-form.md | 69 - .../enterprise-portal-concepts.md | 101 - .../getting-started-with-enterprise-portal.md | 28 - .../setup-email-notifications.md | 66 - .../with-tyk-self-managed-as-provider.md | 62 - .../portal-customisation/.placeholder | 0 .../configure-webhooks.md | 374 -- .../customise-user-model.md | 80 - .../upgrading/theme-upgrades.md | 112 - .../tyk-enterprise-developer-portal.md | 32 - .../api-consumer-portal.md | 21 - .../api-consumer-portal/access-api-product.md | 60 - .../api-consumer-portal/register-portal.md | 45 - .../api-consumer-portal/reset-password.md | 45 - .../api-access/api-access.md | 29 - .../api-access/approve-requests.md | 42 - .../configuring-custom-rate-limit-keys.md | 74 - .../api-access/manage-apps-credentials.md | 36 - .../content-manager-workflow.md | 24 - .../create-new-page-template.md | 142 - .../full-customisation/developer-workflow.md | 25 - .../edit-manage-page-content.md | 44 - .../full-customisation/email-customization.md | 89 - .../file-structure-concepts.md | 189 - .../full-customisation/full-customisation.md | 19 - .../full-customisation/menus-customisation.md | 88 - .../full-customisation/templates.md | 1902 ---------- .../quick-customisation.md | 109 - .../create-api-product-and-plan.md | 67 - .../customise-menus.md | 60 - ...age-get-started-guides-for-api-products.md | 106 - .../publish-api-products-and-plans.md | 78 - .../with-tyk-self-managed-as-provider.md | 55 - .../managing-access/add-organisations.md | 46 - .../approve-self-registering-requests.md | 45 - .../managing-access/invite-codes.md | 48 - .../manage-api-consumer-organisations.md | 119 - .../managing-access/manage-api-consumers.md | 39 - .../managing-access/manage-api-users.md | 46 - .../managing-access/manage-catalogues.md | 59 - .../managing-access/managing-access.md | 23 - tyk-docs/data/menu.yaml | 333 +- 62 files changed, 6187 insertions(+), 6550 deletions(-) rename tyk-docs/content/{tyk-stack/tyk-developer-portal/enterprise-developer-portal/api-access/dynamic-client-registration.md => portal/api-access.md} (55%) create mode 100644 tyk-docs/content/portal/customization.md create mode 100644 tyk-docs/content/portal/developers.md create mode 100644 tyk-docs/content/portal/install.md create mode 100644 tyk-docs/content/portal/overview.md rename tyk-docs/content/{tyk-stack/tyk-developer-portal/enterprise-developer-portal/managing-access/enable-sso.md => portal/settings.md} (83%) delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/api-documentation/list-of-endpoints/portal-1.9.0-list-of-endpoints.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/deploy/bootstrapping-portal.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/deploy/install-tyk-enterprise-portal.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/deploy/install-tyk-enterprise-portal/install-portal-using-docker-compose.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/deploy/install-tyk-enterprise-portal/install-portal-using-docker.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/deploy/install-tyk-enterprise-portal/install-portal-using-helm.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/deploy/install-tyk-enterprise-portal/install-portal-using-new-helm.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/deploy/install-tyk-enterprise-portal/install-portal-using-rpm.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/deploy/install-tyk-enterprise-portal/overview.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/getting-started/create-api-product-and-plan.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/getting-started/create-orgs-and-catalogs.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/getting-started/customize-products-and-plans.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/getting-started/customize-sign-up-form.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/getting-started/enterprise-portal-concepts.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/getting-started/getting-started-with-enterprise-portal.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/getting-started/setup-email-notifications.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/getting-started/with-tyk-self-managed-as-provider.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/portal-customisation/.placeholder delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/portal-customisation/configure-webhooks.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/portal-customisation/customise-user-model.md delete mode 100644 tyk-docs/content/product-stack/tyk-enterprise-developer-portal/upgrading/theme-upgrades.md delete mode 100644 tyk-docs/content/tyk-developer-portal/tyk-enterprise-developer-portal.md delete mode 100644 tyk-docs/content/tyk-developer-portal/tyk-enterprise-developer-portal/api-consumer-portal.md delete mode 100644 tyk-docs/content/tyk-developer-portal/tyk-enterprise-developer-portal/api-consumer-portal/access-api-product.md delete mode 100644 tyk-docs/content/tyk-developer-portal/tyk-enterprise-developer-portal/api-consumer-portal/register-portal.md delete mode 100644 tyk-docs/content/tyk-developer-portal/tyk-enterprise-developer-portal/api-consumer-portal/reset-password.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/api-access/api-access.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/api-access/approve-requests.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/api-access/configuring-custom-rate-limit-keys.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/api-access/manage-apps-credentials.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/content-manager-workflow.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/create-new-page-template.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/developer-workflow.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/edit-manage-page-content.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/email-customization.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/file-structure-concepts.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/full-customisation.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/menus-customisation.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/templates.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/quick-customisation.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/getting-started-with-enterprise-portal/create-api-product-and-plan.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/getting-started-with-enterprise-portal/customise-menus.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/getting-started-with-enterprise-portal/manage-get-started-guides-for-api-products.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/getting-started-with-enterprise-portal/publish-api-products-and-plans.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/getting-started-with-enterprise-portal/with-tyk-self-managed-as-provider.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/managing-access/add-organisations.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/managing-access/approve-self-registering-requests.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/managing-access/invite-codes.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/managing-access/manage-api-consumer-organisations.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/managing-access/manage-api-consumers.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/managing-access/manage-api-users.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/managing-access/manage-catalogues.md delete mode 100644 tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/managing-access/managing-access.md diff --git a/tyk-docs/config.toml b/tyk-docs/config.toml index ecae5a8395..485bb7bd49 100755 --- a/tyk-docs/config.toml +++ b/tyk-docs/config.toml @@ -7,6 +7,8 @@ enableGitInfo = true disableKinds = ["term","taxonomy"] canonifyURLs = false timeout = "60s" +refLinksErrorLevel = "WARNING" +refLinksNotFoundURL = "" [params] GithubEdit = "https://github.com/TykTechnologies/tyk-docs/edit/master/tyk-docs/content/" GithubReadOnly = "https://github.com/TykTechnologies/tyk-docs/blob/master/tyk-docs/content/" diff --git a/tyk-docs/content/developer-support/faq.md b/tyk-docs/content/developer-support/faq.md index 41c96d1898..a45525e3d9 100644 --- a/tyk-docs/content/developer-support/faq.md +++ b/tyk-docs/content/developer-support/faq.md @@ -100,6 +100,42 @@ This section lists commonly asked questions or frequently encountered issues and - For *Amazon RDS* users, check their [backup and restore documentation](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_CommonTasks.BackupRestore.html). To further enhance your PostgreSQL backup process, you can explore services like [AWS RDS Automated Backups](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithAutomatedBackups.html) if you're hosting your database on AWS. - For *CosmosDB* users check their [online backup and on-demand data restore documentation](https://learn.microsoft.com/en-us/azure/cosmos-db/postgresql/concepts-backup) +## Enterprise Developer Portal + +1. **What happens if the Portal goes down ?** + + In the event of the portal application being down, the other components of the Tyk Stack will remain unaffected. + This means your APIs will still be operational, and analytics will continue to be recorded. + Developers will also be able to use their credentials for both oAuth2.0 and API Keys APIs. + + However, since the portal application is down, developers won't be able to access their credentials or the analytical dashboard, request access to new API Products, or revoke or rotate their access credentials. + Additionally, admin users won't be able to use the portal, whether through its UI or APIs. + This means you won't be able to create, change, or remove any item managed by the portal, such as developers, organizations, content pages, API Products, plans, and more. + + Despite this, you still have some control over access credentials. + If you need to rotate or remove access credentials, you can do so directly in the Tyk Dashboard or in your identity provider. + +2. **What happens if the Dashboard goes down ?** + + If the Tyk Dashboard goes down, developers will still be able to access their access credentials, but they won't be able to rotate or remove their existing credentials, or request access to API Products. + Additionally, the API Analytics dashboard will be compromised. + + However, API traffic will remain unaffected, meaning that your APIs will continue to be operational, and analytics will continue to be recorded. + + In terms of admin functionality, the only limitation will be the inability to approve or reject access requests or revoke or rotate access credentials. + + +3. **Does the portal support SQL databases for storing the portal's CMS assets ?** + + {{< note success >}} + **Note** + + Tyk no longer supports SQLite as of Tyk 5.7.0. To avoid disruption, please transition to [PostgreSQL]({{< ref"planning-for-production/database-settings/postgresql#introduction" >}}), [MongoDB]({{< ref "planning-for-production/database-settings/mongodb" >}}), or one of the listed compatible alternatives. + {{< /note >}} + + The Enterprise Developer Portal supports SQL databases (MariaDB, MySQL, and PostgreSQL) for storing the portal's CMS assets. + During the bootstrap process, the portal will create the appropriate tables in the main database. The only thing required to enable SQL storage for the portal's assets is to specify the `db` [storage type]({{< ref "/product-stack/tyk-enterprise-developer-portal/deploy/configuration#portal_storage" >}}) either via a config file or an environment variable. + ## Tyk Gateway 1. **How to Check Your Gateway Version ?** diff --git a/tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/api-access/dynamic-client-registration.md b/tyk-docs/content/portal/api-access.md similarity index 55% rename from tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/api-access/dynamic-client-registration.md rename to tyk-docs/content/portal/api-access.md index b1d14e068a..0e9f68a161 100644 --- a/tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/api-access/dynamic-client-registration.md +++ b/tyk-docs/content/portal/api-access.md @@ -1,12 +1,11 @@ --- -title: "Dynamic client registration" -date: 2022-02-11 -tags: ["Tyk Developer Portal","Enterprise Portal", "Dynamic client registration", "DCR"] -description: "How to configure the Dynamic client registration flow with the Enterprise Portal" -menu: - main: - parent: "API Access" -weight: 5 +title: "API Providers" +date: 2022-02-10 +linkTitle: API Management +tags: [""] +description: "" +aliases: + - /tyk-stack/tyk-developer-portal/enterprise-developer-portal/api-access/dynamic-client-registration --- {{< note success >}} @@ -16,7 +15,180 @@ If you are interested in getting access contact us at [support@tyk.io](}} -## Introduction +## How to Manage API Access? + +The Tyk Enterprise Developer portal provides a special container for access credentials - an application. Applications hold developer credentials that can be used to access APIs published on the portal with a specific plan. A sample relationship between applications, credentials, API Products, and plans is demonstrated in the diagram below. + +{{< img src="/img/dashboard/portal-management/enterprise-portal/portal-apps-structure.png" alt="Sample application setup" >}} + +Credentials are generated by the Tyk Dashboard when an admin user approves a provisioning request or when provisioning requests are configured to be approved automatically. The provisioning flow is demonstrated in the diagram below. + +{{< img src="/img/dashboard/portal-management/enterprise-portal/portal-provisioning-flow.png" alt="Portal provisioning flow" >}} + +This section describes how admin users can manage applications and configure the settings of provisioning requests. + +## Provisioning Request + +### Approve or Reject Provisioning Request + +When an external developer is looking to access a specific API(s) as a part of an API Product, they will request access via the public facing portal. + +**Prerequisites** + +- A Tyk Enterprise portal installation +- A portal admin app login +- Log in to a provisioning request sent by an external API consumer + +**Step by step instructions** + +1. Log in to the portal admin app +2. Navigate to **Provisioning Requests** +3. Select which request you want to approve +4. Click the **more** symbol and select either **approve** or **reject** + +{{< img src="/img/dashboard/portal-management/enterprise-portal/approve-request.png" alt="Approve or reject an API provisioning request" >}} + +### Configure Auto Approval + +You can auto approve provisioning requests. From the **Plans** section of the admin app, edit a plan and select **Auto-approve provisioning request** from the **Plan Settings**. By default this setting is not selected, requiring manual approval of each request. Click **Save Changes** to enable this setting. + +{{< img src="/img/dashboard/portal-management/enterprise-portal/auto-approve-requests.png" alt="Auto Approve API provisioning requests" >}} + +## Manage Apps and Credentials + +**Prerequisites** + +- A Tyk Enterprise portal installation +- A portal admin app login +- A login to the already created app by an external API consumer + +### To view existing apps + +1. In the portal admin app, go to **Apps**. If there are some apps already created by external API-consumers, you’ll see them in the overview list. +{{< img src="/img/dashboard/portal-management/enterprise-portal/list-of-app-admin-app.png" alt="List of applications" >}} + +2. Click on an app from the overview page. +3. On the right hand slideout, you will see the information about the created app. + +### Revoke app credentials + +1. In the portal admin app, go to **Apps** and open the app. +2. Click **credentials**. This means the developer will no longer be able to access the API Product via the selected plan. These actions will have an immediate effect. + +## Manage Catalogs + +Catalogs are a way for you to tailor the audience for API products and Plans. You can, for example create a Partner Catalog, with a specific API product tailored to them and a preferential plan not available in your public portal. + +In this section, you will learn about how catalogs work and how to create a new catalog to expose your API products and plans. + +**Prerequisites** + +- Connect to a provider [Tyk Self-Managed]({{< ref "product-stack/tyk-enterprise-developer-portal/getting-started/with-tyk-self-managed-as-provider" >}}) +- Create [policies with enforced access rights]({{< ref "product-stack/tyk-enterprise-developer-portal/getting-started/create-api-product-and-plan" >}}) (API Product in the Portal) +- Create one or more [policies with enforced rate limit and quotas]({{< ref "/product-stack/tyk-enterprise-developer-portal/getting-started/create-api-product-and-plan.md" >}}) (Plan in the Portal) + +### Create a New Catalog + +1. Navigate to the **Catalog section** section + + {{< img src="/img/dashboard/portal-management/enterprise-portal/catalogue-menu.png" alt="Catalogue menu" >}} + +2. Click Create a new catalog + + {{< img src="/img/dashboard/portal-management/enterprise-portal/portal-managing-access-create-catalogue.png" alt="Create a new catalogue" >}} + +3. Enter Name and Path URL + + {{< img src="/img/dashboard/portal-management/enterprise-portal/portal-managing-access-add-name.png" alt="Name the new catalogue" >}} + +4. Set the access required for the catalog e.g. Public, Private or Custom + + - Public: External developers can access the catalog + - Private: The catalog is only visible to developers that are logged in + - Custom: Only selected teams can access this catalog + +5. [If creating a custom catalog] Under Audience, select one or multiple teams that you want to have access to this catalog. + +{{< note success >}} +**Note** + +For this audience to apply, the visibility needs to be set to custom. + +{{< /note >}} + +6. Select the catalog content in terms of which API Products and plans this catalog should contain. + + + +## Configure Rate Limits + +Different business models may require applying rate limits and quotas not only by credentials but also by other entities, e.g. per application, per developer, per organization etc. +For example, if an API Product is sold to a B2B customer, the quota of API calls is usually applied to all developers and their respective applications combined, in addition to a specific credential. + +To enable this, Tyk introduced support for custom rate limit keys in [Tyk 5.3.0]({{< ref "developer-support/release-notes/dashboard#530-release-notes" >}}). This guide explains how to configure custom rate limit keys. + +**Prerequisites** + +This capability works with [Tyk 5.3.0]({{< ref "developer-support/release-notes/dashboard#530-release-notes" >}}) or higher. + +### Configuring custom rate limit keys for policies in Tyk Dashboard + +Custom rate limit keys are applied at a policy level. When a custom rate limit key is specified, quota, rate limit and throttling will be calculated against the specified value and not against a credential ID. + +To specify a custom rate limit key, add to a policy a new metadata field called `rate_limit_pattern`. +In the value field you can specify any value or expression that you want to use as a custom rate limit key for your APIs. +The `rate_limit_pattern` field supports referencing session metadata using `$tyk_meta.FIELD_NAME` syntax. +In addition, it's possible to concatenate multiple values together using the pipe operator (`|`). + +For instance, if you want to specify a rate limit pattern to calculate the rate limit for a combination of developers and plans, where all credentials of a developer using the same plan share the same rate limit, you can use the following expression. +This assumes that the `DeveloperID` and `PlanID` metadata fields are available in a session: + +```gotemplate +$tyk_meta.DeveloperID|$tyk_meta.PlanID +``` + +Here's how it looks like in the Tyk Dashboard UI: + +{{< img src="/img/dashboard/portal-management/enterprise-portal/configuring-custom-rate-limit-keys.png" alt="Configuring custom rate limit keys" >}} + +
+ +{{< note success >}} +**Updating credential metadata** + +Please note that the custom rate limit key capability uses only metadata objects, such as credentials metadata available in a session. +Therefore, if the `rate_limit_pattern` relies on credentials metadata, this capability will work only if those values are present. +If, after evaluating the `rate_limit_pattern`, its value is equal to an empty string, the rate limiter behavior defaults to rate limiting by credential IDs. + +{{< /note >}} + +### Using custom rate limit keys with the portal + +The Tyk Enterprise Developer Portal facilitates the configuration of various rate limiting options based on a business model for API Products published in the portal. + +To achieve this, the portal, by default, populates the following attributes in the credential metadata, which can be used as part of a custom rate limit key: +- **ApplicationID**: The ID of the application to which the credential belongs. +- **DeveloperID**: The ID of the developer who created the credential. +- **OrganizationID**: The ID of the organization to which the developer belongs. + +Additionally, it's possible to attach [custom attribute values]({{< ref "product-stack/tyk-enterprise-developer-portal/portal-customisation/customise-user-model#add-attributes-to-the-user-model" >}}) defined in a developer profile as metadata fields to credentials. + +When a credential is provisioned by the portal, all the fields described above are added as metadata values to the credential, making them valid options for configuring the rate limit key: + +{{< img src="/img/dashboard/portal-management/enterprise-portal/credential-metadata.png" alt="Credential's metadata" >}} + +This approach allows the portal to seamlessly apply rate limits based on any combination of the aforementioned fields and other custom metadata objects defined in policies used for plans or products. This is in addition to credentials. + +--- + +{{< note success >}} +**Tyk Enterprise Developer Portal** + +If you are interested in getting access contact us at [support@tyk.io]() + +{{< /note >}} + +## Dynamic Client Registration **Why OAuth2.0 is important** @@ -37,10 +209,10 @@ Tyk Enterprise Developer portal allows API providers to set up a connection with
-## Prerequisites for getting started +### Prerequisites Before getting starting with configuring the portal, it's required to configure your Identity provider and the Dashboard beforehand. -### Create an initial access token +#### Create an initial access token Before setting up Tyk Enterprise Developer Portal to work with DCR, you need to configure the identity provider. Please refer to the guides for popular providers to create the initial access token for DCR: * [Gluu](https://gluu.org/docs/gluu-server/4.0/admin-guide/openid-connect/#dynamic-client-registration) * [Curity](https://curity.io/docs/idsvr/latest/token-service-admin-guide/dcr.html) @@ -53,7 +225,7 @@ Before setting up Tyk Enterprise Developer Portal to work with DCR, you need to Whilst many providers require initial access tokens, they are optional. Please refer to your provider documentation to confirm if required. {{< /note >}} -### Create OAuth2.0 scopes to enforce access control and rate limit +#### Create OAuth2.0 scopes to enforce access control and rate limit Tyk uses OAuth2.0 scope to enforce access control and rate limit for API Products. Therefore, creating at least two scopes for an API Product and plan is required. The below example demonstrates how to achieve that with Keycloak: @@ -74,7 +246,7 @@ When using Keycloak, ensure that you set the type of the scope to be `Optional`. {{< img src="/img/dashboard/portal-management/enterprise-portal/old-keycloak-version-client-scope.png" alt="Client Scope Assigned Type" >}} -### Create Tyk policies for an API Product and plan +#### Create Tyk policies for an API Product and plan Navigate to the Tyk Dashboard and create two policies: one for a plan and one for an API Product. Both policies should include only the APIs with JWT authentication that you want to bundle as an API Product. @@ -85,7 +257,7 @@ Navigate to the Tyk Dashboard and create two policies: one for a plan and one fo {{< img src="/img/dashboard/portal-management/enterprise-portal/create-jwt-policy-for-plan.png" alt="Create a policy for a plan" >}} -### Create the No Operation policy and API +#### Create the No Operation policy and API Tyk requires any API that uses the scope to policy mapping to have [a default policy]({{< ref "/api-management/client-authentication#use-json-web-tokens-jwt" >}} ). Access rights and rate limits defined in the default policy take priority over other policies, including policies for the API Product and plan. To avoid that, you need to create the No Operation API and policy that won't grant access to the APIs included in the API Product but will satisfy the requirement for a default policy. @@ -116,7 +288,7 @@ Create a new policy and select the No Operation API in the `Add API Access Right Configure the No Operation policy and save it: {{< img src="/img/dashboard/portal-management/enterprise-portal/save-the-noop-policy.png" alt="Save the No Operation policy" >}} -### Configure scope to policy mapping +#### Configure scope to policy mapping To enforce policies for the API Product and plan, you need to configure the scope to policy mapping for each API included in the API Product. To achieve that, perform the following steps for each API included in the API Product. @@ -142,12 +314,12 @@ To achieve that, perform the following steps for each API included in the API Pr -## Configure Tyk Enterprise Developer Portal to work with an identity provider +### Configure Tyk Enterprise Developer Portal to work with an identity provider Once policies for the plan and product are created, and the scope-to-policy mapping is configured for all APIs that are included in the product, it's time to set up the portal to work with your IdP. -### Configure the App registration settings +#### Configure the App registration settings In the portal, navigate to the `OAuth2.0 Providers` menu section. In that section, you need to configure the connection settings to the IdP and define one or more types (configurations) of OAuth 2.0 clients. For instance, you can define two types of OAuth 2.0 clients: * A confidential client that supports the Client credential grant type for backend integrations; @@ -156,7 +328,7 @@ In the portal, navigate to the `OAuth2.0 Providers` menu section. In that sectio Each configuration of OAuth 2.0 client could be associated with one or multiple API Products so that when an API Consumer requests access to an API Product, they can select a client type that is more suitable for their use case. -#### Specify connection setting to your IdP +##### Specify connection setting to your IdP To connect the portal to the IdP, you need to specify the following settings: * OIDC well-known configuration URL. @@ -168,7 +340,7 @@ Then you need to specify the connection settings: [the initial access token and {{< img src="/img/dashboard/portal-management/enterprise-portal/specify-connection-setting-to-your-idp.png" alt="Specify connection setting to the IdP" >}} -#### Create client configurations +##### Create client configurations Once the connection settings are specified, you need to create one or multiple types of clients. You might have multiple types of clients that are suitable for different use cases, such as backend integration or web applications. You need at least one type of client for the DCR flow to work. To add the first client type, scroll down to the `Client Types` section and click on the `Add client type` button. @@ -187,10 +359,10 @@ Please note that your IdP might override some of these settings based on its con An example of configuration is demonstrated below. After configuring a client type, scroll to the top of the page to save it by clicking on the `SAVE CHANGES` button. {{< img src="/img/dashboard/portal-management/enterprise-portal/configure-type-of-client.png" alt="Configure a client type" >}} -### Configure API Products and plans for the DCR flow +#### Configure API Products and plans for the DCR flow Once the App registration settings are configured, it is time for the final step: to configure the API Products and plans to work with the DCR flow. -#### Configure API Products for the DCR flow +##### Configure API Products for the DCR flow To configure API Products to work with the DCR flow, you need to: * Enable the DCR flow for the products you want to work with the DCR flow. * Associate each product with one or multiple types of clients that were created in the previous step. @@ -204,18 +376,18 @@ Finally, select one or multiple types of clients that were created in [the Creat {{< img src="/img/dashboard/portal-management/enterprise-portal/configure-api-products-for-the-dcr-flow.png" alt="Configure an API Product to work with the DCR flow" >}} -#### Configure plans for the DCR flow +##### Configure plans for the DCR flow The last step is to configure the plans you want to use with the DCR flow. To do this, go to the portal's `Plans` menu section and specify the OAuth2.0 scope to use with each plan. You should have at least one scope that was created in [the Prerequisites for getting started]({{< ref "tyk-stack/tyk-developer-portal/enterprise-developer-portal/api-access/dynamic-client-registration#prerequisites-for-getting-started" >}}). If you need to specify more than one scope, you can separate them with spaces. {{< img src="/img/dashboard/portal-management/enterprise-portal/configure-plan-for-the-dcr-flow.png" alt="Configure a plan to work with the DCR flow" >}} -## Test the DCR flow +### Test the DCR flow To test the DCR flow, you need to perform the following actions: - Request access to the API product and plan you have selected for the DCR flow as a developer. - Approve the access request as an admin. - As a developer, copy the access credentials and obtain an access token. - As a developer, make an API call to verify the flow's functionality. -### Request access to the API Product +#### Request access to the API Product To request access to the DCR enabled API Product: - Log in as a developer and navigate to the catalog page. - Select the DCR enabled API Product and add it to the shopping cart. @@ -225,11 +397,11 @@ To request access to the DCR enabled API Product: - Finally, select the applicable type of client and click on the `Submit request` button. {{< img src="/img/dashboard/portal-management/enterprise-portal/request-access-to-the-dcr-enabled-product.png" alt="Request access to the DCR enabled product" width="600" >}} -### Approve the access request +#### Approve the access request To approve the access request, navigate to the `Access requests` menu in the portal, select the access request and approve it by clicking on the `Approve` button. {{< img src="/img/dashboard/portal-management/enterprise-portal/approve-dcr-access-request.png" alt="Approve DCR access request" >}} -### Obtain an access token +#### Obtain an access token Once the access request is approved, the developer should receive an email informing them of the approval. Please refer to [the email customization section]({{< ref "tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/email-customization.md" >}}) if you wish to change the email template. As a developer, navigate to the `My Dashboard` section in the developer portal, select the application, and copy the OAuth 2.0 credentials. @@ -249,7 +421,7 @@ Since in this example we use the client_secret_basic token endpoint authenticati As a result, you should receive a JWT access token containing the required scopes: {{< img src="/img/dashboard/portal-management/enterprise-portal/jwt.png" alt="An example of a JWT" width="600" >}} -### Make an API Call +#### Make an API Call Finally, use the access token to make an API call and test the flow functionality: ```curl curl --location --request GET 'http://localhost:8080/payment-api/get' \ @@ -271,3 +443,112 @@ You should receive the following response: "url": "http://httpbin.org/get" } ``` + +## Documentation for your API Products + +As an API Provider, you can package APIs into API Products and supply them with documentation to deliver value to your internal and external API Consumers.
+API documentation is essential for API Products. Good API documentation goes beyond just Open API Specification. To make your API Products easy to use and engaging, you can add technical and business guides to the documentation of your API Products, for instance: +* Get started guides explaining how to start with your API Product; +* Use-cases; +* Business documentation that explains the business value and helps to convince decision-makers. + +Tyk Enterprise Developer portal provides two ways of documenting APIs: +* Open API Specifications for APIs; +* The Get started documentation feature enables API Providers to add as many technical and business guides to API Products as needed. + +This section explains how to add the Get started documentation to API Products. + +### Create Get started guides for your API Product + + +1. **Create and publish an API Product** + + To start with, create and publish an API Product. Please refer to the [Publish API Products and Plans]({{< ref "/tyk-stack/tyk-developer-portal/enterprise-developer-portal/getting-started-with-enterprise-portal/publish-api-products-and-plans" >}}) page for further guidance. + +2. **Add API Documentation to API Products** + + To add API Documentation, select an API Product and navigate to the API Documentation section. + Click the ‘Add API Documentation’ button to add a new API Documentation page. + {{< img src="img/dashboard/portal-management/enterprise-portal/api-docs-navigate-to-the-api-docs-section.png" alt="Navigate to the API Documentation section" >}} + +
+ + Tyk developer portal stores two versions of each API Documentation page: in Markdown and HTML formats. + You can edit both versions, but only one version of the page will be displayed. + To edit the Markdown version, click on the ‘Change to Markdown’ button. + {{< img src="img/dashboard/portal-management/enterprise-portal/api-documentation-page-change-to-md.png" alt="Toggle the Markdown editor" >}} + +
+ + To edit the HTML version, click the 'Change to HTML' button. + {{< img src="img/dashboard/portal-management/enterprise-portal/api-documentation-page-change-to-html.png" alt="Toggle the HTML editor" >}} + +
+ + To select which version of the documentation to display, check the ‘Display Markdown’ checkbox. + When it’s checked, the portal will display the Markdown version of the page. + Otherwise, portal will display the HTML version. + {{< img src="img/dashboard/portal-management/enterprise-portal/api-documentation-page-display-md-version.png" alt="Display the MD version of the page" >}} + +3. **Add more documentation pages and set the display order** + + With the Tyk developer portal, you can add multiple Markdown and HTML pages to your API Products and select their display order to form a table of contents suitable for your use case. + Please refer to the previous step to add one more documentation page to the API Product. + + To reorder API Documentation items, scroll down to the API Documentation section and click on the ‘Reorder items’ button. + {{< img src="img/dashboard/portal-management/enterprise-portal/api-documentation-page-start-reordering-docs.png" alt="Reorder API Docs" >}} + +
+ + Then click on the ‘Move up’ button to move an API Documentation item one position up, and the ‘Move down’ button to bring it one position down. Click on the 'Done' button and then on the 'Save' button to save your changes. + {{< img src="img/dashboard/portal-management/enterprise-portal/api-documentation-page-move-doc-up.png" alt="Reorder API Docs" >}} + +
+ + Once you save the changes, the new order of items will be reflected in the ‘Get started’ tab. + {{< img src="img/dashboard/portal-management/enterprise-portal/api-documentation-page-get-started-live.png" alt="Reorder API Docs" >}} + +
+ + All documentation pages are listed in the ‘Product docs’ section. You can access and edit the API docs from that section. + {{< img src="img/dashboard/portal-management/enterprise-portal/product-docs-section.png" alt="Product docs section" >}} + +4. **Add tags to blogs and API Products** + + Finally, you can add blog posts to your API Products using the Tags feature. + You can specify tags for API Product and blog posts, then the blog posts that match tags with an API Product will be displayed in the ‘Related blog content’ section. + {{< img src="img/dashboard/portal-management/enterprise-portal/tags-diagram.png" alt="Tags diagram" width="600" height="314" >}} + +
+ + To specify tags for an API Product, select an API Product, scroll down to the ‘Tags’ section, type in a tag, and press the Enter key. + {{< img src="img/dashboard/portal-management/enterprise-portal/tags-section-in-api-product.png" alt="Specify tags for an API Product" >}} + +
+ + To specify tags for a blog post, select a blog post, scroll down to the ‘Tags’ section, type in a tag, and press the Enter key. + {{< img src="img/dashboard/portal-management/enterprise-portal/tags-section-in-blog-post.png" alt="Specify tags for a blog post" >}} + +
+ + The blog posts that match tags with an API Product will be displayed in the ‘Related blog content’ section of the respective API Product page. + {{< img src="img/dashboard/portal-management/enterprise-portal/related-blog-content.png" alt="Related blog content" width="800" height="925">}} + +--- +--- + +--- + +{{< note success >}} +**Tyk Enterprise Developer Portal** + +If you are interested in getting access contact us at [support@tyk.io]() + +{{< /note >}} + +The Tyk Enterprise Developer Portal has powerful capability of management of API consumer access as single users, teams or organizations. It is possible to create catalogs of API Products with different visibility levels for different teams and organizations. + +The following diagram demonstrates a sample set-up. + +{{< img src="/img/dashboard/portal-management/enterprise-portal/portal-catalogue-sample-set-up.png" alt="Sample API access control setup" >}} + diff --git a/tyk-docs/content/portal/customization.md b/tyk-docs/content/portal/customization.md new file mode 100644 index 0000000000..9766496624 --- /dev/null +++ b/tyk-docs/content/portal/customization.md @@ -0,0 +1,3097 @@ +--- +title: "Developer Portal Customization" +date: 2024-12-24 +linkTitle: API Management +tags: ["portal", "customization",] +description: "Customization options for enterprise developer portal" +aliases: +--- + +{{< note success >}} +**Tyk Enterprise Developer Portal** + +If you are interested in getting access contact us at [support@tyk.io]() + +{{< /note >}} + +## Portal Customization Overview + +The Tyk Enterprise Developer Portal uses themes for customizing the live portal. We provide an out of the box theme that is using our own branding, it’s called the `default` theme. You are welcome to use it and modify it for your needs, yet if you want to start with a blank page, you can also create a completely new theme. + +This section provides a complete guide to full customization from the developer's point of view. + +## Configure Themes + +### What is a Theme? + +The Tyk Enterprise Developer Portal uses **themes** for customizing the live portal. We provide an out of the box theme that is using our own branding, it’s called the `default` theme. You are welcome to use it and modify it for your needs, yet if you want to start with a blank page, you can also create a completely new theme. + +The following section explains how they are structured and their main concepts. We recommend you to read this if you are creating your own theme, or making extensive changes to the ones we provide. + +### File Structure of a Theme + +Generally speaking, a theme defines an application’s styling, templates and scripts. +In the Tyk Developer Portal a `themes` folder is located in the root of the application and is the directory where each theme folder must be added. If you navigate to `path /themes/` you’ll see our default theme which has the following structure: + +{{< img src="/img/dashboard/portal-management/enterprise-portal/theme-file-structure.png" alt="Default Tyk Enterprise Portal theme structure" >}} + +- Manifest file (`theme.json`): It uses JSON syntax to define theme metadata (name, version and author) as well as a list of templates that are part of the theme. +- `assets`: It intended for static assets like CSS, JS or images that are used by the theme. All contents from this directory are mounted under the `/assets` path in the portal HTTP server. +- `layouts`: The layout is the top level view of your theme. +- `views`: The view is rendered as a part of a layout. Each view can be rendered using a different layout. +- `partials`: Partials provide an easier way to handle snippets of code that are reused across different views or layouts, for example if you want to inject a JS snippet that’s used in different places, you could set this code in a partial and include it anywhere by using the appropriate 'Go template directive'. In this way you could improve code readability and organize the theme in the most efficient way. + +#### Manifest File + +This file should sit in the root of a theme and hold the theme configuration. You can define a name and your templates along other options such as the version and the author. + +You can find an example of the manifest within the `default` theme that is located in `/themes/default`. The syntax looks as follows: + +```json +{ + "name": "default", + "version": "0.0.1", + "author": "Tyk Technologies Ltd. ", + "templates": [ + { + "name": "Content Page", + "template": "page", + "layout": "site_layout" + }, + { + "name": "Portal Home", + "template": "portal_home", + "layout": "portal_layout" + }, + { + "name": "Home", + "template": "home", + "layout": "portal_layout" + }, + { + "name": "Catalogue", + "template": "catalogue", + "layout": "portal_layout" + } + ] +} +``` + +The `templates` field establishes a list of available templates. Every template consists of three fields where `name` is a user-friendly name that will be seen on the Admin app when creating a page. `template` is a reference to the template file itself. `layout` is a reference to the layout that will be used to render the previously set template. + +To illustrate the current template hierarchy, this is what a typically rendered page would look like. The `layout` would be the top level template and base structure of the page: +{{< img src="/img/dashboard/portal-management/enterprise-portal/portal-template-layout.png" alt="Template structure" >}} + + +Also note that the Developer Portal will let you use not just multiple `layouts` and `views` but also any combination of them. These combinations are set in your manifest file (`theme.json`). + +Regarding `partials`, even though the illustration above shows two partials embedded on the `view` section, `partials` are intended for using in any place. You should be able to embed a `partial` directly into a layout, or even in multiple layouts. + +Content blocks are explored more deeply in the next sections. To summarise, its relationship with the above hierarchy is when rendering a particular page, a `layout`, a `view` and potentially a combination of partials get loaded from the theme directory. Content blocks are different because their content gets dynamically populated by database content. These contents are created from the Admin section. + +To be Concluded: + +- A layout is the wrapper of everything you want to include inside it. So, typically it would consist of tags such as ``, ``, ``, ``, and `<body>`. +- A `template` is what we would inject in a layout and specifically within the `<body>` of a layout. +- A `partial` can be, for example, the navigation menu so that you can inject it in the layout and it will be visible every time this layout is used + +#### Go Templates + +All theme template files use the Go template syntax. You will find every file in the layouts and views. Partials directory uses the `.tmpl` file extension, which is the default Go template extension. Go templates work in a similar way to ERB or EJS templates by letting the user mix HTML code with dynamic values. Sample syntax is as follows: + +`{{ render “top_nav” }}` + +The code sample above would execute the `render` template helper, which is a common function that’s used to inject code from other `views` into the current one. You may use this to embed content from other parts of the theme, typically `partials` or `views`. In this case, it will insert a `view` or `partial` named `top_nav` to the template where it’s used. + +The same delimiters `{{` and `}}` are used for all Go template directives. We’ll explore some of them in the upcoming sections. + +See the [Go package template documentation](https://pkg.go.dev/text/template#pkg-overview) for more information. + +#### Content Blocks + +The Developer Portal themes use content blocks to facilitate content management. A content block is defined as a part of a `view` by using a particular template directive in combination with a name or ID to identify the given block. For example, if you check the `home` template in the default theme (`themes/default/views/home.tmpl`), you will find the following code: + +```go +div class="container"> + <div class="row"> + <div class="col-sm-6"> + <div class="text-container"> + <h1>{{.page.Title}}</h1> + <p>{{.blocks.HeaderDescription.Content}}</p> + <a href="{{.blocks.HeaderButtonLink.Content}}" class="btn btn-primary">{{.blocks.HeaderButtonLabel.Content}}</a> + </div> +…. +``` + +There are four code references in the above snippet. In this example we have a header, some text and then a button that act as a link. Let's see what each one is and how it correlates with the UI. + +1. `{{ .page.Title }}`. This is the `Title` input in the form UI (Screenshot #1) +1. `{{ .blocks.HeaderDescription.Content }}`. This is the `HeaderDescription` input in the form UI (Screenshot #2) +2. `{{ .blocks.HeaderButtonLink.Content }}`. This is the `HeaderDescription` input in the form UI (Screenshot #3) +3. `{{ .blocks.HeaderButtonLabel.Content }}`. This is the `HeaderButtonLabel` input in the form UI (Screenshot #4) + +{{< img src="/img/dashboard/portal-management/enterprise-portal/go-template-ui.png" alt="Go template blocks and portal UI" >}} + +This will display in your portal as following: + +{{< img src="/img/dashboard/portal-management/enterprise-portal/example-portal-content-block.png" alt="Example Portal content block" >}} + +In order for a page to render properly the content manager will need to be aware of the content blocks that are required by a particular template. + +### Managing Themes + +The Tyk Enterprise Developer Portal enables the admin users and developers to manage themes and select which theme is visible in the portal. +To enable this capability, the portal has theme management UI. + +#### Create a Theme +Follow the example below to create a new theme called "TestTheme" using the default theme as a blueprint: + +1. As an admin user, navigate to the Theme management UI and download the default theme. The Tyk Enterprise Developer Portal doesn't allow modifications to the default theme so that you will always have access to the vanilla theme. + {{< img src="/img/dashboard/portal-management/enterprise-portal/download-default-theme.png" alt="Download default theme" >}} +2. Unzip the theme and rename it by modifying the Manifest file as described above. + {{< img src="/img/dashboard/portal-management/enterprise-portal/rename-a-theme.png" alt="Rename theme" >}} +3. You can also modify other assets in the theme as described later in this guide. Once all modifications are done, you need to zip the theme and upload it to the portal. + {{< img src="/img/dashboard/portal-management/enterprise-portal/compress-a-theme.png" alt="Zip theme" >}} +4. To upload the theme as an admin user, navigate to **Themes** and click on the **Add new theme** button. Please note that the size of individual files should not exceed 5 MB and the total size of all files in the theme should not exceed `PORTAL_MAX_UPLOAD_SIZE`. This parameter is [configurable]({{< ref "product-stack/tyk-enterprise-developer-portal/deploy/configuration#portal_max_upload_size" >}}). + {{< img src="/img/dashboard/portal-management/enterprise-portal/add-a-new-theme.png" alt="Add new theme" >}} +5. Then click on the **Add theme file** button. + {{< img src="/img/dashboard/portal-management/enterprise-portal/add-theme-file.png" alt="Add theme file" >}} +6. Select the archive that you've created earlier and click on the **Save** button. + {{< img src="/img/dashboard/portal-management/enterprise-portal/save-new-theme.png" alt="Save new theme" >}} +7. Now you should see a success message meaning the theme was successfully created. + {{< img src="/img/dashboard/portal-management/enterprise-portal/new-theme-is-created.png" alt="Theme is created" >}} + +#### Preview a Theme +The Tyk Enterprise Developer Portal enables the admin users to preview the theme before it gets reflected on the public-facing portal. This enables to review the changes that are made to the theme before exposing them to the developer community. +1. To preview a theme as an admin user, navigate to the **Themes** menu. Select a theme, and click on the **Preview** button. + {{< img src="/img/dashboard/portal-management/enterprise-portal/preview-theme-button.png" alt="Preview theme" >}} +2. The previewer will open the selected theme in a new tab. Now you can browse your theme and review the changes. For the demonstration purposes, we've modified the API Catalog page so it displays "Modified catalog" instead of "Product Catalogs". + {{< img src="/img/dashboard/portal-management/enterprise-portal/theme-preview.png" alt="Preview theme" >}} +3. Once the review is done, you can quit the preview by clicking on the **Quit preview button**. + {{< img src="/img/dashboard/portal-management/enterprise-portal/quit-theme-preview.png" alt="Quite theme preview" >}} + +#### Activate a Theme +The Tyk Enterprise Developer Portal enables you to have multiple themes at the same time but only one of them is active. +1. As an admin user, navigate to the **Themes** menu. The current status of each theme is displayed in the **Status** column. + {{< img src="/img/dashboard/portal-management/enterprise-portal/default-theme-is-current.png" alt="Default theme is the current theme" >}} +2. To activate the new theme, click on the **Activate** button. + {{< img src="/img/dashboard/portal-management/enterprise-portal/activate-a-theme.png" alt="Activate theme" >}} +3. The selected theme is now active and displayed to all API consumers on the Live portal. + {{< img src="/img/dashboard/portal-management/enterprise-portal/modified-theme-is-active.png" alt="Modified theme is activated" >}} + +#### Modify an Existing Theme +The Tyk Enterprise Developer Portal enables modification to any existing theme, except the default one. +1. To start modification of any existing theme, navigate to the **Themes** menu and download the theme package. + {{< img src="/img/dashboard/portal-management/enterprise-portal/download-a-theme.png" alt="Download existing theme" >}} +2. Unzip the package, do any required modification and zip it back. You should keep the name of the theme. If you need to change the name of the theme, you will need to create a new theme as described above. +3. As an admin user, navigate to the **Themes** menu and select the modified theme. + {{< img src="/img/dashboard/portal-management/enterprise-portal/select-a-modified-theme.png" alt="Select modified theme" >}} +4. Click on the **Add Theme File** button and select the theme archive. + {{< img src="/img/dashboard/portal-management/enterprise-portal/add-theme-file-to-existing-theme.png" alt="Add theme file" >}} +5. Click on the **Save changes** button to save changes to the theme. + {{< img src="/img/dashboard/portal-management/enterprise-portal/save-changes-to-theme.png" alt="Save changes" >}} +6. If the theme is the current changes to the Live portal, it will be applied immediately. Otherwise, you can preview and activate the theme as described above. + +### Upgrading Themes + +The Tyk Enterprise Developer Portal does not automatically update the default theme with each new release of the product, because doing so could result in the loss of customizations made by customers. +Therefore, customers are required to manually upgrade their themes to access the latest updates and fixes. We recommend using GitFlow for the latest theme updates. + +Alternatively, you can download the theme package from the **Releases** section of the [portal-default-theme](https://github.com/TykTechnologies/portal-default-theme) repository. +However, we advise against this method, as it requires you to merge your customized theme with the downloaded one, which is much simpler to accomplish via GitFlow. +Follow the guide below to obtain the latest version of the portal theme and merge it with your customized version. + +#### Merge Latest Changes using Gitflow + +The default theme for the Tyk Enterprise Developer Portal is located in the [portal-default-theme](https://github.com/TykTechnologies/portal-default-theme) repository. +The `main` branch contains code corresponding to the latest stable release. If you wish to check out a specific release (e.g., v1.8.3), you can use tags: + +```console +git checkout tags/1.8.3 -b my-custom-theme branch +``` + +To organize local development in a way that facilitates seamless theme updates using git merge, follow the steps below: +1. Fork the `portal-default-theme` repo in [github](https://github.com/TykTechnologies/portal-default-theme). + {{< img src="/img/dashboard/portal-management/enterprise-portal/fork-portal-theme-repo.png" alt="Fork the portal-theme repo" >}} + +2. Clone the forked repository: +```console +git clone https://github.com/my-github-profile/portal-default-theme && cd ./portal-default-theme +``` + +3. If you have an existing repository, check if you already have the `portal-default-theme` repo among your remotes before adding it. Execute the following command to check: +```console +git remote -v | grep 'TykTechnologies/portal-default-theme' +``` + +Skip the next step if you see the following: +```console +# portal-default-theme https://github.com/TykTechnologies/portal-default-theme (fetch) +# portal-default-theme https://github.com/TykTechnologies/portal-default-theme (push) +``` + +If the output of the above command is empty, proceed to step 5 to add the `portal-default-theme`. + +4. Add the `portal-default-theme` to the remotes by executing the following command: +```console +git remote add portal-default-theme https://github.com/TykTechnologies/portal-default-theme +``` + +5. Create a new local branch that tracks the remote `main` branch. That branch will mirror the latest changes from the `portal-default-theme` main. You will be using it to import the latest changes from the `portal-default-theme` to your custom theme: +```console +git fetch portal-default-theme main:portal-default-theme-main +``` + +If you have an existing local branch that tracks the `main` branch in the `portal-default-theme` repo, you can just pull the latest updates: +```console +git checkout portal-default-theme-main +git pull portal-default-theme main +``` + +6. To start customizing the theme, create a local develop branch from the `portal-default-theme-main`: +```console +git checkout portal-default-theme-main +git checkout -b dev-branch +``` + +7. Once the required customizations are completed, commit the changes to the `dev-branch`. + +8. Merge the latest updates from the `portal-default-theme` into the `dev-branch`. Please remember to always pull the latest changes from the `portal-default-theme-main` branch before merging: + - Checkout to the portal-default-theme-main and fetch the latest changes. + ```console + git checkout portal-default-theme-main + git pull portal-default-theme main + ``` + - Checkout the dev-branch and merge the changes from the portal-default-theme-main to retrieve the latest changes from the portal-default-theme repo with the customized theme. + ```console + git checkout dev-branch + git merge portal-default-theme-main + ``` + +Finally, address merge conflicts and commit changes. + +{{< note success >}} +**You have successfully updated your custom theme** + +Now you can repeat the above described process when upgrading the portal version to make sure you have incorporated the latest theme changes to your customized theme. + +{{< /note >}} + +#### Upload the Theme to the Portal +Once you have merged your local changes with the latest changes from the `portal-default-theme` repo, you need to create a zip archive with the customized theme and upload it to the portal. +1. Create a zip archive with the customized theme. Make sure you zip the content of the `src` folder and not the folder itself. To create a zip archive with the customized theme execute the following: + - cd to the `src` directory to make sure you: + ```console + cd ./src + ``` + - zip the content of the `src` directory: + ```console + zip -r9 default.zip + ``` + +2. Upload the theme package that is created in the previous step to the portal. You can use the portal's [Admin dashboard]({{< ref "/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/file-structure-concepts#part-1-create-a-new-theme" >}}) or the [admin API]({{< ref "/product-stack/tyk-enterprise-developer-portal/api-documentation/tyk-edp-api" >}}) to do it. +![image](https://github.com/TykTechnologies/tyk-docs/assets/14009/f0e547b2-b521-4c3e-97ce-fd3a2a3b170b) +3. Finally, you need to [activate]({{< ref "/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/file-structure-concepts#part-3-activate-a-theme" >}}) the theme so that it will be applied to the portal. + +## Configure Templates + +Templates are a fundamental component of the Tyk Enterprise Developer Portal, enabling dynamic content generation and +customization. The portal uses Golang templates to render the live portal views, allowing you to generate dynamic HTML +by embedding directives inside HTML that are replaced with values when the template is executed. + +Golang's templates use the following syntax: +- `{{ . }}` to output a value +- `{{ .FieldName }}` to access a field of an object +- `{{ .MethodName }}` to call a method on an object +- `{{ if }} {{ else }} {{ end }}` for conditionals +- `{{ range . }} {{ . }} {{ end }}` to iterate over a slice +- Functions can be called like `{{ FuncName . }}` or just `{{ FuncName }}` + +These templates are part of the default theme that ships with the portal, which can be fully customized by modifying the +template files. The templates have access to template data which contains dynamic values that can be rendered into the +HTML. There are also a number of global helper functions available to transform data before output. + +The Tyk Enterprise Developer Portal uses several types of templates to render different parts of the portal: +- Public Pages Templates: Render the portal's publicly accessible pages (such as Home, About Us, and Blog pages), +forming the foundation of your portal's public-facing content. These can be customized through the Pages +[section]({{< ref "/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/edit-manage-page-content" >}}) +of the admin dashboard. +- Private Pages Templates: Responsible for rendering the portal's authenticated user pages, like Profile settings and +My Apps. +- Email Templates: Define the structure and content of emails sent by the portal, such as signup confirmations or access +request approvals. + +Both Public and Private Pages Templates have access to global helper functions (funcmaps) and template-specific data. +Email templates can include template data and specific template functions, but do not have access to the global helper +functions. + +The following sections provide comprehensive information on the various components of the Tyk Enterprise Developer +Portal templates: + +- [Template Data](#template-data): Detailed explanation of the data structures available in different templates. +- [Global Helper Functions](#global-helper-functions): A list of global functions that can be used across templates to +manipulate and display data. +- [Email Templates](#email-templates): Information about email-specific templates and their available data. + +### Template Data + +This section outlines the Tyk Enterprise Developer Portal templates that have access to specific template data. +It's important to note that data availability varies between templates, depending on their context and purpose. +For instance, a product detail template has access to product-specific data that may not be available in a blog listing +template. + +#### Templates with specific template data + +- [Analytics](#analytics) +- [Application Create](#application-create) +- [Application Detail](#application-detail) +- [Blogs](#blogs) +- [Blog Detail](#blog-detail) +- [Cart Checkout](#cart-checkout) +- [Organization User Detail](#organization-user-detail) +- [Organization User Edit](#organization-user-edit) +- [Organization Users List](#organization-users-list) +- [Product Detail](#product-detail) +- [Product OAS Documentation](#product-oas-documentation) + +#### Analytics + +**Template Path**: `themes/default/views/analytics.tmpl` + +This template is used to render the analytics page. + +##### Available Objects + +- `{{ .errors }}`: Map of template errors (Key: category, Value: error message) +- `{{ .apps }}`: List of available applications + +##### Application Attributes + +Accessible via `{{ range .apps }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Application ID | +| `{{ .Name }}` | Application name | +| `{{ .Description }}` | Application description | +| `{{ .RedirectURLs }}` | Application redirect URLs | + +###### Example Usage +```html +<select id="analytics-overview-select-apps" class="analytics-select-overview"> + <option value="0" selected>All apps</option> + {{ range $app := .apps }} + <option value="{{ $app.ID }}"> + {{ $app.Name }} + </option> + {{ end }} +</select> +``` + +#### Application Create + +**Template Path**: `themes/default/views/app_form_create.tmpl` + +This template is used to render the application creation form. + +##### Available Objects + +- `{{ .errors }}`: Map of template errors (Key: category, Value: error message) + +###### Example Usage +```html +{{ if .errors }} +{{ range $key, $errs := .errors }} +<div class="alert alert-warning cart-error" role="alert"> + <i class="tyk-icon tykon tykon-warning"></i> + <div class="alert__content"> + <strong>{{ $key }}</strong> + <ul> + {{ range $errs }} + <li>{{ . }}</li> + {{ end }} + </ul> + </div> +</div> +{{ end }} +{{ end }} +``` + +#### Application Detail + +**Template Path**: `themes/default/views/app_form_update.tmpl` + +This template is used to render the application detail and update form. + +##### Available Objects + +- `{{ .errors }}`: Map of template errors (Key: category, Value: error message) +- `{{ .app }}`: Selected application object. +- `{{ .appCerts }}`: Map of application MTLS certificates if applicable (Key: access request ID, Value: certificate) +- `{{ .allCerts }}`: Map of all MTLS certificates stored if applicable (Key: cert fingerprint, Value: cert) + +##### MTLS Certificate Attributes (appCerts) + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Certificate ID | +| `{{ .Name }}` | Certificate name | +| `{{ .Fingerprint }}` | Certificate fingerprint | +| `{{ .SignatureAlgorithm }}` | Signature algorithm | +| `{{ .Issuer }}` | Certificate issuer | +| `{{ .IsValid }}` | Boolean indicating if the certificate is valid | +| `{{ .ValidNotBefore }}` | Start date of validity | +| `{{ .ValidNotAfter }}` | End date of validity | +| `{{ .Subject }}` | Certificate subject | + +##### MTLS Certificate Attributes (allCerts) + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Certificate ID | +| `{{ .Name }}` | Certificate name | + +##### Client Attributes + +Accessible via `{{ .app }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Client ID | +| `{{ .Name }}` | Client name | +| `{{ .Description }}` | Client description | +| `{{ .RedirectURLs }}` | Client redirect URLs | +| `{{ .Credentials }}` | Array of client credentials | +| `{{ .AccessRequests }}` | Array of client access requests | + +##### Client Credentials Attributes + +Accessible via `{{ range $cred := .app.Credentials }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Credential ID | +| `{{ .Credential }}` | Credential | +| `{{ .CredentialHash }}` | Credential hash | +| `{{ .OAuthClientID }}` | OAuth client ID | +| `{{ .OAuthClientSecret }}` | OAuth client secret | +| `{{ .Expires }}` | Credential expiration | +| `{{ .AccessRequestID }}` | Access request ID associated with the credential | + +##### Client Access Requests Attributes + +Accessible via `{{ range $acreq := .app.AccessRequests }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Access request ID | +| `{{ .Status }}` | Access request status | +| `{{ .UserID }}` | User ID associated with access request | +| `{{ .AuthType }}` | Access request auth type | +| `{{ .DCREnabled }}` | true if access request DCR enabled | +| `{{ .ProvisionImmediately }}` | true if provisioned immediately is enabled | +| `{{ .CatalogueID }}` | Catalogue ID | + +##### Product Attributes (within Access Request) + +Accessible via `{{ $product := $acreq.Product }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Product ID | +| `{{ .Name }}` | Product name | +| `{{ .DisplayName }}` | Product display name | +| `{{ .Path }}` | Product path | +| `{{ .Description }}` | Product description | +| `{{ .Content }}` | Product content | +| `{{ .AuthType }}` | Product auth type | +| `{{ .DCREnabled }}` | true if product DCR enabled | + +##### Plan Attributes (within Access Request) + +Accessible via `{{ $acreq.Plan }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .Name }}` | Plan name | +| `{{ .DisplayName }}` | Plan display name | +| `{{ .Description }}` | Plan description | +| `{{ .AuthType }}` | Plan auth type | +| `{{ .Rate }}` | Plan rate | +| `{{ .Per }}` | Plan period | +| `{{ .QuotaMax }}` | Plan quota maximum | +| `{{ .QuotaRenewalRate }}` | Plan quota renewal rate | +| `{{ .AutoApproveAccessRequests }}` | true if auto-approve access requests is enabled | + +###### Example Usage +```html +<h1>{{ .app.Name >}}</h1> +<p>{{ .app.Description }}</p> +<h2>Credentials</h2> +{{ range $cred := .app.Credentials }} +<div> + <p>ID: {{ $cred.ID }}</p> + <p>OAuth Client ID: {{ $cred.OAuthClientID }}</p> + <p>Expires: {{ $cred.Expires }}</p> +</div> +{{ end }} +<h2>Access Requests</h2> +{{ range $acreq := .app.AccessRequests }} +<div> + <p>ID: {{ $acreq.ID }}</p> + <p>Status: {{ $acreq.Status }}</p> + <p>Product: {{ $acreq.Product.Name }}</p> + <p>Plan: {{ $acreq.Plan.Name }}</p> +</div> +{{ end }} +``` + +#### Blogs + +**Template Path**: `themes/default/views/blog_listing.tmpl` + +This template is used to render the blog listing page. + +##### Available Objects + +- `{{ .posts }}`: List of all published blog posts + +##### Blog Attributes + +Accessible via `{{ range .posts }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .Title }}` | Blog post title | +| `{{ .Lede }}` | Blog post summary | +| `{{ .Content }}` | Blog post content | +| `{{ .MarkdownContent }}` | Markdown content | +| `{{ .MarkdownEnabled }}` | Boolean for Markdown enablement | +| `{{ .Path }}` | Blog post path | +| `{{ .HeaderImage.URL }}` | Header image URL | +| `{{ .BlogSiteID }}` | Blog site ID | +| `{{ .ProductID }}` | Associated product ID | +| `{{ .AuthorID }}` | Author ID | +| `{{ .URL }}` | Full URL of the blog post | + +###### Example Usage +```html +<h1>Blog Posts</h1> +{{ range .posts }} +<div class="blog-post"> + <h2><a href="{{ .URL }}">{{ .Title }}</a></h2> + <img src="{{ .HeaderImage.URL }}" alt="{{ .Title }}"> + <p>{{ .Lede }}</p> +</div> +{{ end }} +``` + +#### Blog Detail + +**Template Path**: `themes/default/views/blog_detail.tmpl` + +This template is used to render the blog detail page. + +##### Available Objects + +- `{{ .post }}`: The selected blog post object. +- `{{ .latest_posts }}`: List of 3 latest blog posts. + +##### Blog Attributes + +Accessible via `{{ .post }}` or `{{ range .latest_posts }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .Title }}` | Blog post title | +| `{{ .Lede }}` | Blog post summary | +| `{{ .Content }}` | Blog post content | +| `{{ .MarkdownContent }}` | Markdown content | +| `{{ .MarkdownEnabled }}` | Boolean for Markdown enablement | +| `{{ .Path }}` | Blog post path | +| `{{ .HeaderImage.URL }}` | Header image URL | +| `{{ .BlogSiteID }}` | Blog site ID | +| `{{ .ProductID }}` | Associated product ID | +| `{{ .AuthorID }}` | Author ID | +| `{{ .URL }}` | Full URL of the blog post | + +###### Example Usage +``` +<h1>{{ .post.Title }}</h1> +<img src="{{ .post.HeaderImage.URL }}" alt="{{ .post.Title }}"> +<p>{{ .post.Lede }}</p> +{{ if .post.MarkdownEnabled }} +{{ .post.MarkdownContent | markdownify }} +{{ else }} +{{ .post.Content }} +{{ end }} +<p>Read more at: <a href="{{ .post.URL }}">{{ .post.URL }}</a></p> +<h2>Latest Posts</h2> +{{ range .latest_posts }} +<div> + <h3><a href="{{ .URL }}">{{ .Title }}</a></h3> + <p>{{ .Lede }}</p> +</div> +{{ end }} +``` + +#### Cart Checkout + +**Template Path**: `themes/default/views/portal_checkout.tmpl` + +This template is used to render the cart checkout page. + +##### Available Objects + +- `{{ .cart }}`: Map with the cart items for the current user +- `{{ .apps }}`: List of applications for the current user +- `{{ .catalogue_count }}`: Cart catalogues count +- `{{ .certs }}`: List of MTLS certificates if applicable +- `{{ .errors }}`: Map of template errors (Key: category, Value: error message) +- `{{ .provisioned }}`: Boolean indicating whether an access request has been provisioned for the cart + +##### Application Attributes + +Accessible via `{{ range .apps }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .Name }}` | Application name | +| `{{ .Description }}` | Application description | +| `{{ .RedirectURLs }}` | Application redirect URLs | + +##### MTLS Certificate Attributes + +Accessible via `{{ range .certs }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Certificate ID | +| `{{ .Name }}` | Certificate name | + +##### Cart Item Attributes + +Accessible via `{{ range $key, $value := .cart }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ $value.AuthType }}` | Cart item auth type | +| `{{ $value.Catalogue }}` | Cart item catalogue | +| `{{ $value.Products }}` | Cart item array of products | +| `{{ $value.Plan }}` | Cart item plan | +| `{{ $value.DCREnabled }}` | true if cart order consists of DCR products | + +##### Plan Attributes (Within cart item) + +Accessible via `{{ $plan := $value.Plan }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Plan ID | +| `{{ .PlanName }}` | Plan name | +| `{{ .FormatQuota }}` | Formatted quota information | +| `{{ .FormatRateLimit }}` | Formatted rate limit information | + +##### Catalogue Attributes (Within cart item) + +Accessible via `{{ $catalogue := $value.Catalogue }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Catalogue ID | + +##### Product Attributes (Within cart item) + +Accessible via `{{ range $product := $value.Products }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Product ID | +| `{{ .Name }}` | Product name | +| `{{ .DisplayName }}` | Product display name | +| `{{ .Path }}` | Product path | +| `{{ .Description }}` | Product description | +| `{{ .Content }}` | Product content | +| `{{ .AuthType }}` | Product auth type | +| `{{ .DCREnabled }}` | true if product DCR enabled | +| `{{ .AuthTypes }}` | List of product auth types | + +##### Auth Type Attributes (Within product) + +Accessible via `{{ range $auth_type := $product.AuthTypes }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .AuthType }}` | Auth type | + +##### DCR Client Template Attributes (Within product) + +Accessible via `{{ range $template := $product.Templates }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Template ID | +| `{{ .Name }}` | Template name | +| `{{ .GrantType }}` | Template grant type | +| `{{ .ResponseTypes }}` | Template response types | +| `{{ .TokenEndpointAuthMethod }}` | Template token endpoint auth method | +| `{{ .OktaAppType }}` | Template Okta app type | + +<details> +<summary> <b>Example Usage</b></summary> + +```html +<h1>Cart Checkout</h1> +{{ range $key, $value := .cart }} +<div class="cart-item"> + <p>Auth Type: {{ $value.AuthType }}</p> + <p>Plan: {{ $value.Plan.Name }}</p> + {{ range $product := $value.Products }} + <div class="product"> + <h3>{{ $product.DisplayName }}</h3> + <p>{{ $product.Description }}</p> + <p>Path: {{ $product.Path }}</p> + </div> + {{ end }} +</div> +{{ end }} +<h2>Your Applications</h2> +{{ range $app := .apps }} +<div class="application"> + <h3>{{ $app.Name }}</h3> + <p>{{ $app.Description }}</p> +</div> +{{ end }} +{{ if .certs }} +<h2>MTLS Certificates</h2> +{{ range $cert := .certs }} +<div class="certificate"> + <p>ID: {{ $cert.ID }}</p> + <p>Name: {{ $cert.Name }}</p> +</div> +{{ end }} +{{ end }} +``` +</details> + + +#### Organization User Detail + +**Template Path**: `themes/default/views/user_detail.tmpl` + +This template is used to render the organization user detail page. + +##### Available Objects + +- `{{ .errors }}`: Map of template errors (Key: category, Value: error message) +- `{{ .user }}`: The organization user object. + +##### User Attributes + +Accessible via `{{ .user }}` + +| Attribute/Method | Description | +|-------------------|-------------| +| `{{ .ID }}` | User ID | +| `{{ .First }}` | User name | +| `{{ .Last }}` | User surname | +| `{{ .Email }}` | User email | +| `{{ .OrganisationID }}` | User organization ID | +| `{{ .DisplayName }}` | User complete name | +| `{{ .IdentityProvider }}` | User provider (Portal or Tyk Identity Broker) | +| `{{ .GetOrganisationID }}` | User's organization ID | +| `{{ .IsAdmin }}` | true if user is an admin | +| `{{ .IsOrgAdmin }}` | true if user is an organization admin | +| `{{ .DisplayRole }}` | User's role | + + +<details> +<summary> <b>Example Usage</b></summary> + +```html +<h1>User Details</h1> +{{ if .errors }} +{{ range $key, $errs := .errors }} +<div class="alert alert-warning cart-error error-wrapper" role="alert"> + <i class="tyk-icon tykon tykon-warning"></i> + <div class="alert__content"> + <strong>{{ $key }}</strong> + <ul> + {{ range $errs }} + <li>{{ . }}</li> + {{ end }} + </ul> + </div> +</div> +{{ end }} +{{ end }} +<p>Name: {{ .user.DisplayName }}</p> +<p>Email: {{ .user.Email }}</p> +<p>Role: {{ .user.DisplayRole }}</p> +``` + +</details> + +#### Organization User Edit + +**Template Path**: `themes/default/views/user_edit.tmpl` + +This template is used to render the edit page for organization user. + +##### Available Objects + +- `{{ .errors }}`: Map of template errors (Key: category, Value: error message) +- `{{ .roles }}`: List of possible roles +- `{{ .user }}`: The organization user object. + +##### Role Attributes + +Accessible via `{{ range .roles }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Role ID | +| `{{ .DisplayName }}` | Role display name | + +##### User Attributes + +Accessible via `{{ .user }}` + +| Attribute/Method | Description | +|-------------------|-------------| +| `{{ .ID }}` | User ID | +| `{{ .First }}` | User name | +| `{{ .Last }}` | User surname | +| `{{ .Email }}` | User email | +| `{{ .OrganisationID }}` | User organization ID | +| `{{ .DisplayName }}` | User complete name | +| `{{ .IdentityProvider }}` | User provider (Portal or Tyk Identity Broker) | +| `{{ .GetOrganisationID }}` | User's organization ID | +| `{{ .IsAdmin }}` | true if user is an admin | +| `{{ .IsOrgAdmin }}` | true if user is an organization admin | +| `{{ .DisplayRole }}` | User's role | + +<details> +<summary> <b>Example Usage</b></summary> + +```html +<form action="edit" method="post" id="user-edit"> + {{ if .error }} + <div class="alert alert-danger" role="alert"> + {{ .error }} + </div> + {{ end }} + <h2>Developer details</h2> + <div> + <label>Name:</label> + <input type="text" name="first" value="{{ .user.First }}" required /> + </div> + <div> + <label>Last name:</label> + <input type="text" name="last" value="{{ .user.Last }}" required /> + </div> + <div> + <label>Email:</label> + <input type="email" name="email" value="{{ .user.Email }}" required disabled /> + </div> + {{ if .roles }} + <div> + <label>Role:</label> + <select name="role" required> + {{ range $role := .roles }} + <option value="{{ $role.ID }}">{{ $role.DisplayName }}</option> + {{ end }} + </select> + </div> + {{ end }} + <div> + <a href="/portal/private/users">Cancel</a> + <input type="submit" value="Save Changes" /> + </div> +</form> +``` + +</details> + +#### Organization Users List + +**Template Path**: `themes/default/views/user_list.tmpl` + +This template is used to render the list of organization users. + +##### Available Objects + +- `{{ .roles }}`: Map of available roles (Key: role, Value: role display name) + +###### Example Usage +```html +<td> {{ index $roles $userInvite.Role }} </td> +{{ end }} +``` + +#### Product Detail + +**Template Path**: `themes/default/views/portal_product_detail.tmpl` + +This template is used to render the product detail page. + +##### Available Objects + +- `{{ .product }}`: The selected product object +- `{{ .catalogues }}`: List of catalogue objects including the selected product +- `{{ .unique_plans }}`: List of plan objects available for the product +- `{{ .scopes }}`: Product scopes as an array of strings +- `{{ .posts }}`: List of related blog post objects +- `{{ .errors }}`: Map of template errors (Key: category, Value: error message) +- `{{ .added }}`: Boolean indicating if the product is added to the cart + +##### Product Attributes + +Accessible via `{{ .product }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Product ID | +| `{{ .Name }}` | Product name | +| `{{ .DisplayName }}` | Product display name | +| `{{ .Path }}` | Product path | +| `{{ .ReferenceID }}` | Product reference ID | +| `{{ .Description }}` | Product description | +| `{{ .AuthType }}` | Product auth type | +| `{{ .Logo.URL }}` | Product logo URL | +| `{{ .Feature }}` | true if the product is featured | +| `{{ .DCREnabled }}` | true if DCR is enabled | +| `{{ .ProviderID }}` | Provider ID | + +##### API Details (Within product) + +Accessible via `{{ .product.APIDetails }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .Name }}` | API name | +| `{{ .Description }}` | API description | +| `{{ .APIType }}` | API type | +| `{{ .TargetURL }}` | API target URL | +| `{{ .ListenPath }}` | API listen path | +| `{{ .OASUrl }}` | API OAS URL | +| `{{ .Status }}` | "Active" if API status is active, otherwise "Inactive" | + +##### Documentation (Within product) + +Accessible via `{{ .product.Docs }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .Title }}` | Document title | +| `{{ .ID }}` | Document identifier | +| `{{ .Content }}` | Document content | +| `{{ .MarkdownContent }}` | Markdown content | +| `{{ .MarkdownEnabled }}` | Boolean for Markdown enablement | + +##### Catalogues + +Accessible via `{{ range .catalogues }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .Name }}` | Catalogue name | +| `{{ .VisibilityStatus }}` | Catalogue visibility status | + +##### Plans + +Accessible via `{{ range .unique_plans }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .Name }}` | Plan name | +| `{{ .ID }}` | Plan ID | +| `{{ .DisplayName }}` | Plan display name | +| `{{ .Description }}` | Plan description | +| `{{ .AuthType }}` | Plan authentication type | +| `{{ .Rate }}` | Plan rate | +| `{{ .Per }}` | Plan rate per time unit | +| `{{ .QuotaMax }}` | Plan maximum quota | +| `{{ .QuotaRenewalRate }}` | Plan quota renewal rate | +| `{{ .AutoApproveAccessRequests }}` | Boolean for auto-approval of access requests | + +##### Related Posts + +Accessible via `{{ range .posts }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .Title }}` | Post title | +| `{{ .Lede }}` | Post summary | +| `{{ .Content }}` | Post content | +| `{{ .MarkdownContent }}` | Markdown content | +| `{{ .MarkdownEnabled }}` | Boolean for Markdown enablement | +| `{{ .Path }}` | Post path | +| `{{ .HeaderImage.URL }}` | Header image URL | +| `{{ .BlogSiteID }}` | Blog site ID | +| `{{ .ProductID }}` | Associated product ID | +| `{{ .AuthorID }}` | Author ID | + +<details> +<summary> <b>Example Usage</b></summary> + +```html +<div class="product-detail"> + <h1>{{ .product.DisplayName }}</h1> + <img src="{{ .product.Logo.URL }}" alt="{{ .product.Name }} logo"> + <p>{{ .product.Description }}</p> + <h2>API Details</h2> + {{ range .product.APIDetails }} + <h3>{{ .Name }}</h3> + <p>Status: {{ .Status }}</p> + <p>Target URL: {{ .TargetURL }}</p> + {{ end }} + <h2>Documentation</h2> + {{ range .product.Docs }} + <h3>{{ .Title }}</h3> + {{ if .MarkdownEnabled }} + {{ .MarkdownContent | markdownify }} + {{ else }} + {{ .Content }} + {{ end }} + {{ end }} + <h2>Available in Catalogues</h2> + <ul> + {{ range .catalogues }} + <li>{{ .Name }} ({{ .VisibilityStatus }})</li> + {{ end }} + </ul> + <h2>Available Plans</h2> + {{ range .unique_plans }} + <div class="plan"> + <h3>{{ .DisplayName }}</h3> + <p>{{ .Description }}</p> + <p>Rate: {{ .Rate }} per {{ .Per }}</p> + <p>Quota: {{ .QuotaMax }}</p> + </div> + {{ end }} + <h2>Related Posts</h2> + {{ range .posts }} + <div class="related-post"> + <h3><a href="{{ .Path }}">{{ .Title }}</a></h3> + <img src="{{ .HeaderImage.URL }}" alt="{{ .Title }}"> + <p>{{ .Lede }}</p> + </div> + {{ end }} +</div> +``` + +</details> + +#### Product OAS Documentation + +**Template Paths**: +- `themes/default/views/product_doc_stoplight_spec.tmpl` +- `themes/default/views/product_doc_redoc.tmpl` + +These templates are used to render the OpenAPI Specification (OAS) documentation for a product. The Stoplight Spec and +ReDoc versions are available. + +##### Available Attributes + +| Attribute | Description | +|-----------|-------------| +| `{{ .Name }}` | Product name | +| `{{ .Description }}` | Product description | +| `{{ .Path }}` | Product path | +| `{{ .Url }}` | OAS document URL | + +<details> +<summary> <b>Example Usage</b></summary> + +```html +<div class="docs-container"> + <div class="card mt-4"> + <div class="card-body"> + <h3 class="card-title"> + <a href="/portal/catalogue-products/{{ .Path }}">{{ .Name }}</a> + </h3> + <p class="card-text"> + {{ .Description }} + </p> + </div> + </div> + <div> + <elements-api + apiDescriptionUrl='{{ .Url }}' + router="hash" + layout="responsive" + /> + </div> +</div> +``` + +</details> + +### Global Helper Functions + +This section provides a detailed overview of the global helper functions available in the Tyk Enterprise Developer +Portal templates. These functions are accessible across the public and private templates and allow you to perform +various operations, retrieve specific data, and create dynamic content within your templates. + +#### Available Functions + +- [CanCreateOrganisation](#cancreateorganisation) +- [Clients](#clients) +- [Current User](#currentuser) +- [FeaturedProducts](#featuredproducts) +- [FilterUserInvites](#filteruserinvites) +- [FormatTime](#formattime) +- [GetCart](#getcart) +- [GetCatalogueList](#getcataloguelist) +- [GetCataloguesForProduct](#getcataloguesforproduct) +- [GetClientDescription](#getclientdescription) +- [GetClientName](#getclientname) +- [GetMenus](#getmenus) +- [GetProducts](#getproducts) +- [IsPortalDisabled](#isportaldisabled) +- [IsPortalPrivate](#isportalprivate) +- [ProductDocRenderer](#productdocrenderer) +- [ProviderUpstreamURL](#providerupstreamurl) +- [SplitStrings](#splitstrings) +- [TruncateString](#truncatestring) +- [TypeOfCredential](#typeofcredential) + +##### CanCreateOrganisation + +Returns true if user can create an organization. + +###### Example Usage +``` +{{ if CanCreateOrganisation req }} + ... +{{ end }} +``` + +##### Clients + +Returns the list of applications for the current user. Expects the request as argument. + +###### Client Attributes + +Accessible via `{{ range $client := Clients req }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ $client.ID }}` | Client ID | +| `{{ $client.Name }}` | Client name | +| `{{ $client.Description }}` | Client description | +| `{{ $client.RedirectURLs }}` | Client redirect URLs | +| `{{ $client.Credentials }}` | Array of client credentials | +| `{{ $client.AccessRequests }}` | Array of client access requests | + +###### Credential Attributes (Within client) + +Accessible via `{{ range $cred := $client.Credentials }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ $cred.ID }}` | Credential ID | +| `{{ $cred.Credential }}` | Credential | +| `{{ $cred.CredentialHash }}` | Credential hash | +| `{{ $cred.OAuthClientID }}` | OAuth client ID | +| `{{ $cred.OAuthClientSecret }}` | OAuth client secret | +| `{{ $cred.Expires }}` | Credential expiration | +| `{{ $cred.AccessRequestID }}` | Access request ID associated with the credential | + +###### Access Request Attributes (Within client) + +Accessible via `{{ range $acreq := $client.AccessRequests }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ $acreq.ID }}` | Access request ID | +| `{{ $acreq.Status }}` | Access request status | +| `{{ $acreq.UserID }}` | User ID associated with access request | +| `{{ $acreq.AuthType }}` | Access request auth type | +| `{{ $acreq.DCREnabled }}` | true if access request DCR enabled | +| `{{ $acreq.ProvisionImmediately }}` | true if provisioned immediately is enabled | +| `{{ $acreq.CatalogueID }}` | Catalogue ID | + +###### Product Attributes (Within access request) + +Accessible via `{{ range $product := $acreq.Products }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ $product.ID }}` | Product ID | +| `{{ $product.Name }}` | Product name | +| `{{ $product.DisplayName }}` | Product display name | +| `{{ $product.Path }}` | Product path | +| `{{ $product.Description }}` | Product description | +| `{{ $product.Content }}` | Product content | +| `{{ $product.AuthType }}` | Product auth type | +| `{{ $product.DCREnabled }}` | true if product DCR enabled | + +###### Plan Attributes (Within access request) + +Accessible via `{{ $acreq.Plan }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .Name }}` | Plan name | +| `{{ .DisplayName }}` | Plan display name | +| `{{ .Description }}` | Plan description | +| `{{ .AuthType }}` | Plan auth type | +| `{{ .Rate }}` | Plan rate | +| `{{ .Per }}` | Plan period | +| `{{ .QuotaMax }}` | Plan quota maximum | +| `{{ .QuotaRenewalRate }}` | Plan quota renewal rate | +| `{{ .AutoApproveAccessRequests }}` | true if auto-approve access requests is enabled | + +###### Example Usage +```html +{{ range $client := Clients req }} +<div class="client"> + <h2>Client: {{ $client.Name }}</h2> + {{ range $acreq := $client.AccessRequests }} + <h4>Products:</h4> + <ul> + {{ range $product := $acreq.Products }} + <li> + <strong>{{ $product.Name }}</strong> + {{ $product.Description }} + </li> + {{ end }} + </ul> + <h4>Plan:</h4> + <p><strong>Name:</strong> {{ $acreq.Plan.Name }}</p> + <p><strong>Rate:</strong> {{ $acreq.Plan.Rate }} per {{ $acreq.Plan.Per }}</p> + <p><strong>Quota Max:</strong> {{ $acreq.Plan.QuotaMax }}</p> + {{ end }} +</div> +{{ end }} +``` + +##### CurrentUser + +The `CurrentUser` function returns the current user object if a user is logged in. It expects the request as an argument. + +##### User Attributes + +Accessible via `{{ $user := CurrentUser req }}` + +| Attribute/Method | Description | +|-------------------|-------------| +| `{{ $user.ID }}` | User ID | +| `{{ $user.First }}` | User name | +| `{{ $user.Last }}` | User surname | +| `{{ $user.Email }}` | User email | +| `{{ $user.OrganisationID }}` | User organization ID | +| `{{ $user.DisplayName }}` | User complete name | +| `{{ $user.IdentityProvider }}` | User provider (Portal or Tyk Identity Broker) | +| `{{ $user.GetOrganisationID }}` | User's organization ID | +| `{{ $user.IsAdmin }}` | true if user is an admin | +| `{{ $user.IsOrgAdmin }}` | true if user is an organization admin | +| `{{ $user.DisplayRole }}` | User's role | + +###### Example Usage +```html +{{ $user := CurrentUser req }} +{{ if $user }} +<div class="user-info"> + <h2>Welcome, {{ $user.DisplayName }}!</h2> + <p>Email: {{ $user.Email }}</p> + {{ if $user.IsAdmin }} + <p>You have admin privileges.</p> + {{ else if $user.IsOrgAdmin }} + <p>You are an organization admin.</p> + {{ else }} + <p>Your role: {{ $user.DisplayRole }}</p> + {{ end }} +</div> +{{ else }} +<p>Please log in to view your account information.</p> +{{ end }} +``` + +##### FeaturedProducts + +Returns a list of featured products. + +###### Product Attributes + +Accessible via `{{ range FeaturedProducts }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Product ID | +| `{{ .Name }}` | Product name | +| `{{ .DisplayName }}` | Product display name | +| `{{ .Path }}` | Product path | +| `{{ .ReferenceID }}` | Product reference ID | +| `{{ .Description }}` | Product description | +| `{{ .AuthType }}` | Product auth type | +| `{{ .Scopes }}` | Product scopes | +| `{{ .Logo.URL }}` | Product logo URL | +| `{{ .Feature }}` | true if the product is featured | +| `{{ .DCREnabled }}` | true if DCR is enabled | +| `{{ .ProviderID }}` | Provider ID | +| `{{ .APIDetails }}` | Array of API details associated with the product | +| `{{ .Catalogues }}` | Array of catalogues associated with the product | + +###### API Details Attributes (Within product) + +Accessible via `{{ range .APIDetails }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .Name }}` | API name | +| `{{ .Description }}` | API description | +| `{{ .APIType }}` | API type | +| `{{ .TargetURL }}` | API target URL | +| `{{ .ListenPath }}` | API listen path | +| `{{ .OASUrl }}` | API OAS URL | +| `{{ .Status }}` | "Active" if API status is active, otherwise "Inactive" | + +###### Catalogue Attributes (Within product) + +Accessible via `{{ range .Catalogues }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .Name }}` | Catalogue name | +| `{{ .VisibilityStatus }}` | Catalogue visibility status | + +<details> +<summary> <b>Example Usage</b></summary> + +```html +{{ $featured_products := FeaturedProducts }} +<h2>Featured API Products</h2> +<p>Explore our highlighted API offerings</p> +<div class="featured-products-container"> + {{ range $featured_products }} + <div class="product-card"> + {{ if .Logo }} + <img src="{{ .Logo.URL }}" alt="{{ .Name }} logo"> + {{ end }} + <div class="product-info"> + <span class="auth-type">{{ .AuthType }}</span> + <h3>{{ .Name }}</h3> + <p>{{ .Description }}</p> + </div> + <div class="product-actions"> + <a href="/portal/catalogue-products/{{ .Path }}" class="btn">More Info</a> + <div class="dropdown-content"> + {{ range .APIDetails }} + {{ if or (gt (.OASDocument.Base.Url | trim | length) 0) (gt (.OASUrl | trim | length) 0) }} + <a href="/portal/catalogue-products/{{ $.Path }}/{{ .APIID }}/docs" target="blank"> + {{ .Name }} + </a> + {{ end }} + {{ end }} + </div> + </div> + </div> + {{ end }} +</div> +``` + +</details> + +##### FilterUserInvites + +Returns a list of users that were invited to the current user's organization, if the user became an organization. +Expects the request as a parameter. + +###### User Attributes + +Accessible via `{{ range $invite := FilterUserInvites req }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ $invite.ID }}` | User ID | +| `{{ $invite.Email }}` | User email | +| `{{ $invite.First }}` | User first name | +| `{{ $invite.Last }}` | User last name | +| `{{ $invite.Role }}` | User role | +| `{{ $invite.JoinedAt }}` | User joined at time | +| `{{ $invite.Joined }}` | Whether the user has joined | +| `{{ $invite.Uactive }}` | Whether the user is active | + +<details> +<summary> <b>Example Usage</b></summary> + +```html +{{ $userInvites := FilterUserInvites req }} +{{ if $userInvites }} +<h2>Invited Users</h2> +<table> + <thead> + <tr> + <th>Name</th> + <th>Email</th> + <th>Role</th> + <th>Status</th> + </tr> + </thead> + <tbody> + {{ range $invite := $userInvites }} + <tr> + <td>{{ $invite.First }} {{ $invite.Last }}</td> + <td>{{ $invite.Email }}</td> + <td>{{ $invite.Role }}</td> + <td> + {{ if $invite.Joined }} + Joined + {{ else if $invite.Uactive }} + Pending + {{ else }} + Inactive + {{ end }} + </td> + </tr> + {{ end }} + </tbody> +</table> +{{ else }} +<p>No pending invitations.</p> +{{ end }} +``` + +</details> + +##### FormatTime + +Formats a given time with a given format. + +###### Example Usage +```gotemplate +{{ $user := CurrentUser req }} +{{ if $user}} +{{$time := FormatTime $user.CreatedAt "2 Jan, 2006 at 3:04:00 PM (MST)"}} +<!-- Use $time or other variables here --> +... +{{end}} +``` + +##### GetCart + +Returns a map with the cart items for a given user ID. Expects the user ID as an argument. This function is useful for +retrieving and displaying the contents of a user's cart, including detailed information about the products, their +authentication types, and associated templates. + +###### Cart Item Attributes + +Accessible via `{{ range $key, $value := GetCart $user.ID }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ $value.AuthType }}` | Cart item auth type | +| `{{ $value.Catalogue }}` | Cart item catalogue | +| `{{ $value.DCREnabled }}` | true if cart order consists of DCR products | +| `{{ $value.Plan }}` | Cart item plan | +| `{{ $value.Products }}` | Cart item array of products | + +##### Plan Attributes (Within cart item) + +Accessible via `{{ $plan := $value.Plan }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Plan ID | +| `{{ .PlanName }}` | Plan name | +| `{{ .FormatQuota }}` | Formatted quota information | +| `{{ .FormatRateLimit }}` | Formatted rate limit information | + +##### Catalogue Attributes (Within cart item) + +Accessible via `{{ $catalogue := $value.Catalogue }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Catalogue ID | + +###### Product Attributes (Within cart item) + +Accessible via `{{ range $product := $value.Products }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Product ID | +| `{{ .Name }}` | Product name | +| `{{ .DisplayName }}` | Product display name | +| `{{ .Path }}` | Product path | +| `{{ .Description }}` | Product description | +| `{{ .Content }}` | Product content | +| `{{ .AuthType }}` | Product auth type | +| `{{ .DCREnabled }}` | true if product DCR enabled | +| `{{ .AuthTypes }}` | List of product auth types | + +###### DCR Client Template Attributes (Within product) + +Accessible via `{{ range $template := $product.Templates }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .ID }}` | Template ID | +| `{{ .Name }}` | Template name | +| `{{ .GrantType }}` | Template grant type | +| `{{ .ResponseTypes }}` | Template response types | +| `{{ .TokenEndpointAuthMethod }}` | Template token endpoint auth method | +| `{{ .OktaAppType }}` | Template Okta app type | + +###### Example Usage +```html +{{ $user := CurrentUser req }} +{{ if $user }} + {{ $cart := GetCart $user.ID }} + {{ if $cart }} + <h2>Your Cart</h2> + {{ range $key, $value := $cart }} + <div class="cart-item"> + <h3>{{ $value.Catalogue.Name }}</h3> + <p>Auth Type: {{ $value.AuthType }}</p> + {{ range $product := $value.Products }} + <div class="product"> + <h4>{{ $product.DisplayName }}</h4> + <p>{{ $product.Description }}</p> + </div> + {{ end }} + </div> + {{ end }} + {{ else }} + <p>Your cart is empty.</p> + {{ end }} +{{ end }} +``` + +##### GetCatalogueList + +Returns a list of catalogue names. Expects the request as parameter. + +###### Example Usage +```gotemplate +{{ range $key, $value := GetCatalogueList req }} +<option value="{{ $key }}" {{ if eq $value.Selected true }} selected {{ end }}>{{ $value.Name }}</option> +{{ end }} +``` + +##### GetCataloguesForProduct + +Returns a list of products for a given user and product ID. Expects the request, a user and a product ID as parameters. + +###### Catalogue Attributes + +Accessible via `{{ range GetCataloguesForProduct req $user $product.ID }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .VisibilityStatus }}` | Catalogue visibility status | +| `{{ .Name }}` | Catalogue name | + +###### Example Usage +```html +{{ $thisProduct := .product }} +{{ $user := CurrentUser req }} +{{ $catalogues_for_product := GetCataloguesForProduct req $user $thisProduct.ID }} +<h3>Catalogues for {{ $thisProduct.Name }}</h3> +<ul> + {{ range $catalogues_for_product }} + <li> + <strong>{{ .Name }}</strong> + (Visibility: {{ .VisibilityStatus }}) + </li> + {{ end }} +</ul> +``` + +##### GetClientDescription + +Returns an application description given a credential ID. + +###### Example Usage +``` +{{ range $app.Credentials }} +... +{{ GetClientDescription .ID}} +{{end}} +``` + +##### GetClientName + +Returns an application name given a credential ID. + +###### Example Usage +``` +{{ range $app.Credentials }} +... +{{ GetClientName .ID}} +{{end}} +``` + +##### GetMenus + +Returns a map of all [menus]({{< ref "/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/menus-customisation" >}}). + +###### Example Usage +```html +{{ if GetMenus.Primary }} + {{ range GetMenus.Primary.Children }} + {{ range .Children }} + <li class="nav-item"> + <a class="dropdown-item" href="{{ .Path }}">{{ .Tag }}</a> + </li> + {{ end }} + {{ end }} +{{ end }} +``` + +##### GetProducts + +Returns the list of products for the current user. Expects the request as an argument. + +###### Product Attributes + +Accessible via `{{ range $product := GetProducts req }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ $product.ID }}` | Product ID | +| `{{ $product.Name }}` | Product name | +| `{{ $product.DisplayName }}` | Product display name | +| `{{ $product.Path }}` | Product path | +| `{{ $product.ReferenceID }}` | Product reference ID | +| `{{ $product.Description }}` | Product description | +| `{{ $product.AuthType }}` | Product auth type | +| `{{ $product.Scopes }}` | Product scopes | +| `{{ $product.Logo.URL }}` | Product logo URL | +| `{{ $product.Feature }}` | true if the product is featured | +| `{{ $product.DCREnabled }}` | true if DCR is enabled | +| `{{ $product.ProviderID }}` | Provider ID | +| `{{ $product.APIDetails }}` | Array of API details associated with the product | +| `{{ $product.Catalogues }}` | Array of catalogues associated with the product | + +###### API Details Attributes (Within product) + +Accessible via `{{ range $api := $product.APIDetails }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ $api.Name }}` | API name | +| `{{ $api.Description }}` | API description | +| `{{ $api.APIType }}` | API type | +| `{{ $api.TargetURL }}` | API target URL | +| `{{ $api.ListenPath }}` | API listen path | +| `{{ $api.OASUrl }}` | API OAS URL | +| `{{ $api.Status }}` | "Active" if API status is active, otherwise "Inactive" | + +###### Catalogue Attributes (Within product) + +Accessible via `{{ range $catalogue := $product.Catalogues }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ $catalogue.Name }}` | Catalogue name | +| `{{ $catalogue.VisibilityStatus }}` | Catalogue visibility status | + +<details> +<summary> <b>Example Usage</b></summary> + +```html +{{ range GetProducts req }} +<div class="col-lg-12 card-container"> + <div class="card d-flex flex-row {{ if .Logo.URL }}has-logo{{ end }}"> + {{ if .Logo.URL }} + <img class="card-img-top img-fluid" src="{{ .Logo.URL }}" alt=""> + {{ end }} + <div class="card-body align-self-center w-100"> + <div class="card-title d-flex flex-column justify-content-end align-items-baseline"> + <div class="pill-container"> + <span class="pill">{{ .AuthType }}</span> + </div> + <h2>{{ .ProductName }}</h2> + </div> + {{ if .Description }} + <p class="card-text">{{ .Description }}</p> + {{ end }} + </div> + <div class="card-cta d-flex flex-column align-self-center justify-content-between align-items-baseline w-100"> + <div> + <a href="/portal/catalogue-products/{{ .Path }}" class="btn btn-secondary">More Info</a> + </div> + </div> + </div> +</div> +{{ end }} +``` + +</details> + +##### IsPortalDisabled + +Returns true (exception: for admins is always enabled) if portal visibility was set to hidden. Expects the request as +parameter. + +###### Example Usage +``` +{{ $portalDisabled := IsPortalDisabled req }} +``` + +##### IsPortalPrivate + +Returns true (exception: for admins is always enabled) if portal visibility was set to private. Expects the request as +parameter. + +###### Example Usage +``` +{{ $portalPrivate := IsPortalPrivate req }} +``` + +##### ProductDocRenderer + +Returns the configured product OAS renderer (redoc or stoplight). + +###### Example Usage +``` +{{ $oas_template := ProductDocRenderer }} +``` + +##### ProviderUpstreamURL + +Returns the provider upstream URL for a given providerID. Expects the request and a provider ID as parameters. + +###### Example Usage +``` +{{ $upstreamURL := ProviderUpstreamURL req $thisProduct.ProviderID }} +``` + +##### SplitStrings + +Splits a given string with given separator and returns a slice of split strings. + +###### Example Usage +``` +{{ range $app.Credentials }} +... +{{ range SplitStrings .GrantType "," }} +... +{{ end }} +{{ end }} +``` + +##### TruncateString + +Truncates a given string to a given length, returning the truncated string followed by three dots (…). + +###### Example Usage +``` +{{ TruncateString $api.Description 60 }} +``` + +##### TypeOfCredential + +Returns the credential type ("oAuth2.0" or "authToken") given the credential. + +###### Example Usage +``` +{{ range $app.Credentials }} +... +{{ if eq (TypeOfCredential . ) "oAuth2.0" }} +... +{{ end }} +{{end}} +``` + + +### Email Templates + +This section provides a detailed overview of the email template data available in the Tyk Enterprise Developer Portal. +The Tyk Enterprise Developer Portal uses a variety of email templates for different purposes, such as user registration +and access request status or organization status updates. Each template has access to specific data or functions relevant +to its purpose. + +It's important to note that while email templates can include template data or specific template functions, they do not +have access to the global helper functions available in other portal templates. + +Please refer to [email workflow]({{< ref "/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/email-customization" >}}) +for additional detail on email notifications sent by the portal. + + +#### Available Email Templates + +- [Access Request Approve/Reject](#access-request-approvereject) +- [Access Request Submitted](#access-request-submitted) +- [Activate and Deactivate](#activate-and-deactivate) +- [New User Request](#new-user-request) +- [Organization Approve](#organization-approve) +- [Organization Reject](#organization-reject) +- [Organization Request](#organization-request) +- [Reset Password](#reset-password) +- [Targeted Invite](#targeted-invite) +- [Welcome User](#welcome-user) + +##### Access Request Approve/Reject + +**Template Paths**: +- `themes/default/mailers/approve.tmpl` +- `themes/default/mailers/reject.tmpl` + +These templates are used for sending notifications to users when their access requests are approved or rejected. + +###### Available Objects + +There's no data sent to these templates. + +###### Example Usage +``` +Hi, +The API Credentials you provisioned have been rejected. +Thanks, +The Team +``` + +##### Access Request Submitted + +**Template Path**: `themes/default/mailers/submitted.tmpl` + +This template is used for notifying administrators about pending access requests. + +###### Available Objects + +- `{{ .requests }}`: Returns the list of access requests pending approval. + +###### Access Request Attributes + +Accessible via `{{ range .requests }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ .PlanID }}` | Plan ID associated with access request | +| `{{ .Status }}` | Request status | +| `{{ .AuthType }}` | Request authentication type | +| `{{ .UserID }}` | User ID associated with the request | +| `{{ .ClientID }}` | Client ID associated with the request | +| `{{ .DCREnabled }}` | Indicates if DCR (Dynamic Client Registration) is enabled for the request | +| `{{ .ProvisionImmediately }}` | Indicates if provisioning is immediate for the request | +| `{{ .CatalogueID }}` | Catalogue ID associated with the request | + +###### Product Attributes (within Access Request) + +Accessible via `{{ range $product := $acreq.Products }}` + +| Attribute | Description | +|-----------|-------------| +| `{{ $product.ID }}` | Product ID | +| `{{ $product.Name }}` | Product name | +| `{{ $product.DisplayName }}` | Product display name | +| `{{ $product.Description }}` | Product description | +| `{{ $product.AuthType }}` | Product authentication type | +| `{{ $product.DCREnabled }}` | Indicates if DCR (Dynamic Client Registration) is enabled for the product | + +###### Example Usage +```html +<p>A new Access request has been submitted. Please log in to the administration dashboard to view the request.</p> +<ul> + {{ range $acreq := .requests }} + <li> + <strong>Status:</strong> {{ $acreq.Status }}<br> + <strong>User ID:</strong> {{ $acreq.UserID }}<br> + <strong>Products:</strong> + <ul> + {{ range $product := $acreq.Products }} + <li>{{ $product.DisplayName }} ({{ $product.AuthType }})</li> + {{ end }} + </ul> + </li> + {{ end }} +</ul> +``` + + +##### Activate and Deactivate + +**Template Paths**: +- `themes/default/mailers/activate.tmpl` +- `themes/default/mailers/deactivate.tmpl` + +These templates are used for sending activation and deactivation notifications to users. + +###### Available Objects + +- `{{ .name }}`: Returns the user's full name. + +###### Example Usage +``` +Hi, <strong>{{.name}}</strong><br/> +Your account has been activated. +``` + +##### New User Request + +**Template Path**: `themes/default/mailers/newuser.tmpl` + +This template is used for notifying administrators about new user registration requests pending activation. + +###### Available Objects + +- `{{ .user }}`: Returns the new user pending activation. + +##### User Attributes + +Accessible via `{{ .user }}` + +| Attribute/Method | Description | +|-------------------|-------------| +| `{{ .ID }}` | User ID | +| `{{ .First }}` | User name | +| `{{ .Last }}` | User surname | +| `{{ .Email }}` | User email | +| `{{ .OrganisationID }}` | User organization ID | +| `{{ .DisplayName }}` | User complete name | +| `{{ .IdentityProvider }}` | User provider (Portal or Tyk Identity Broker) | +| `{{ .GetOrganisationID }}` | User's organization ID | +| `{{ .IsAdmin }}` | true if user is an admin | +| `{{ .IsOrgAdmin }}` | true if user is an organization admin | +| `{{ .DisplayRole }}` | User's role | +| `{{ .Organisation.Name }}` | Organization name | +| `{{ .Teams }}` | Array of user teams | +| `{{ .Teams.ID }}` | Team ID | +| `{{ .Teams.Name }}` | Team name | +| `{{ .Teams.Default }}` | Indicates if the team is the default team (true/false) | + +###### Example Usage +``` +<p>There is a new user request pending. Please approve it from the admin console.</p> +<p> + Id: {{ .user.ID }}<br/> + User: {{ .user.DisplayName }} ({{ .user.Email }})<br/> + Role: {{ .user.Role }}<br/> + {{ if gt .user.OrganisationID 0 }} + Organisation: {{ .user.Organisation.Name }}<br/> + {{ else }} + Organisation: Administrators' organisation<br/> + {{ end }} + {{ if gt (len .user.Teams) 0 }} + Teams:<br/> + <ul> + {{ range .user.Teams }} + <li>{{ .Name }}</li> + {{ end }} + </ul> + {{ else }} + Teams: none + {{ end }} +</p> +``` + +##### Organization Approve + +**Template Path**: `themes/default/mailers/organisation_request.tmpl` + +This template is used for notifying users that their organization creation request has been approved. + +###### Available Objects + +- `{{ site }}`: Returns the application host. + +###### Example Usage +``` +Hello, +The organization registration request has been approved. You can now manage your organization in your dashboard here: https://{{.site}}/portal/private/dashboard +Thanks, +The team +``` + +##### Organization Reject + +**Template Path**: `themes/default/mailers/organisation_reject.tmpl` + +This template is used for notifying users that their organization creation request has been rejected. + +###### Available Objects + +There's no data sent to this template. + +###### Example Usage +``` +Hello, +The organization registration request has been rejected. +Thanks, +The team +``` + +##### Organization Request + +**Template Path**: `themes/default/mailers/organisation_request.tmpl` + +This template is used for notifying administrators about new organization creation requests. + +###### Available Objects + +- `{{ .user }}`: Returns the user who made the request. +- `{{ .organisationName }}`: Returns the new organization name. + +##### User Attributes + +Accessible via `{{ .user }}` + +| Attribute/Method | Description | +|-------------------|-------------| +| `{{ .ID }}` | User ID | +| `{{ .First }}` | User name | +| `{{ .Last }}` | User surname | +| `{{ .Email }}` | User email | +| `{{ .OrganisationID }}` | User organization ID | +| `{{ .DisplayName }}` | User complete name | +| `{{ .IdentityProvider }}` | User provider (Portal or Tyk Identity Broker) | +| `{{ .GetOrganisationID }}` | User's organization ID | +| `{{ .IsAdmin }}` | true if user is an admin | +| `{{ .IsOrgAdmin }}` | true if user is an organization admin | +| `{{ .DisplayRole }}` | User's role | + +###### Example Usage +``` +There is a new organization registration request pending. Please approve it from the admin console. +The organization name: {{ .organisationName }}. +The user: {{ .user.DisplayName }} ({{ .user.Email }}). +``` + +##### Reset Password + +**Template Path**: `themes/default/mailers/auth/reset_password.tmpl` + +This template is used for sending password reset emails to users. + +###### Available Functions + +- `{{ current_user }}`: Returns the current user object. +- `{{ reset_password_url }}`: Returns the URL with the token for setting the password. + +###### User Attributes + +Accessible via `{{ current_user }}` + +| Attribute/Method | Description | +|-------------------|-------------| +| `{{ .ID }}` | User ID | +| `{{ .First }}` | User name | +| `{{ .Last }}` | User surname | +| `{{ .Email }}` | User email | +| `{{ .Role }}` | User role | +| `{{ .OrganisationID }}` | User organization ID | +| `{{ .DisplayName }}` | User complete name | +| `{{ .IdentityProvider }}` | User provider (Portal or Tyk Identity Broker) | +| `{{ .GetOrganisationID }}` | User's organization ID | +| `{{ .IsAdmin }}` | true if user is an admin | +| `{{ .IsOrgAdmin }}` | true if user is an organization admin | +| `{{ .DisplayRole }}` | User's role | + +###### Example Usage +``` +{{ $user := current_user}} +<p>Hello {{ $user.DisplayName }},</p> +<p>Someone has requested a link to change your password. You can do this through the link below.</p> +<p>{{reset_password_url}}</p> +<p>If you didn't request this, please ignore this email.</p> +<p>Your password won't change until you access the link above and create a new one.</p> +``` + +##### Targeted Invite + +**Template Path**: `themes/default/mailers/auth/targeted_invite.tmpl` + +This template is used for sending targeted invitations to users. + +###### Available Functions + +- `{{ user }}`: Returns the targeted user object. +- `{{ team }}`: Returns the team name to which the user is being invited. +- `{{ invite_url }}`: Returns the URL with the token for setting the password. + +###### User Attributes + +Accessible via `{{ user }}` + +| Attribute/Method | Description | +|-------------------|-------------| +| `{{ .ID }}` | User ID | +| `{{ .First }}` | User name | +| `{{ .Last }}` | User surname | +| `{{ .Email }}` | User email | +| `{{ .Role }}` | User role | +| `{{ .OrganisationID }}` | User organization ID | +| `{{ .DisplayName }}` | User complete name | +| `{{ .IdentityProvider }}` | User provider (Portal or Tyk Identity Broker) | +| `{{ .GetOrganisationID }}` | User's organization ID | +| `{{ .IsAdmin }}` | true if user is an admin | +| `{{ .IsOrgAdmin }}` | true if user is an organization admin | +| `{{ .DisplayRole }}` | User's role | + +###### Example Usage +```html +{{ $u := user }} +Hi, <strong>{{ $u.DisplayName }}</strong><br/> +<p>Someone is inviting you to join {{ if $u.IsAdmin }}as an Administrator{{ else }}the {{ team }} team{{end }}. You can do this through the link below.</p> +<p>{{ invite_url }}</p> +<p>If you didn't request this, please ignore this email.</p> +``` + +##### Welcome User + +**Template Paths**: +- `themes/default/mailers/welcome_admin.tmpl` +- `themes/default/mailers/welcome_dev.tmpl` + +These templates are used for sending welcome emails to new users, with separate templates for administrators and developers. + +###### Available Objects + +- `{{ .user }}`: Returns the user who made the request. Refer to the CurrentUser section for accessible attributes and methods. + +##### User Attributes + +Accessible via `{{ .user }}` + +| Attribute/Method | Description | +|-------------------|-------------| +| `{{ .ID }}` | User ID | +| `{{ .First }}` | User name | +| `{{ .Last }}` | User surname | +| `{{ .Email }}` | User email | +| `{{ .OrganisationID }}` | User organization ID | +| `{{ .DisplayName }}` | User complete name | +| `{{ .IdentityProvider }}` | User provider (Portal or Tyk Identity Broker) | +| `{{ .GetOrganisationID }}` | User's organization ID | +| `{{ .IsAdmin }}` | true if user is an admin | +| `{{ .IsOrgAdmin }}` | true if user is an organization admin | +| `{{ .DisplayRole }}` | User's role | +| `{{ .Organisation.Name }}` | organization name | +| `{{ .Teams }}` | Array of user teams | +| `{{ .Teams.ID }}` | Team ID | +| `{{ .Teams.Name }}` | Team name | +| `{{ .Teams.Default }}` | Indicates if the team is the default team (true/false) | + +<details> +<summary> <b>Example Usage</b></summary> + +```html +<h1>Welcome to Tyk Enterprise Developer Portal</h1> +<p>Hello {{ .user.DisplayName }},</p> +<p>Your account has been created for the {{ .user.Organisation.Name }} organisation.</p> +<p>Your assigned teams:</p> +<ul> + {{ range .user.Teams }} + <li>{{ .Name }}{{ if .Default }} (Default){{ end }}</li> + {{ end }} +</ul> +<p>We're excited to have you on board!</p> +``` + +</details> + +## Configure Pages + +We suggest you read the [portal concepts]({{< ref "/product-stack/tyk-enterprise-developer-portal/getting-started/enterprise-portal-concepts" >}}) first. If you've already done that, we will show you an example on how to: + +- create a new layout. +- create a new template from the file system. +- create a new page from the admin dashboard. + +**Prerequisites** + +- Access to the file system +- Access to your Tyk Self-Managed installation + +### Create a New Page using an Existing Template + +Follow the example below to create a new page called “My first page” using an existing template. + +{{< img src="/img/dashboard/portal-management/enterprise-portal/create-new-page1.png" alt="The pages section within the Tyk Enterprise Portal app" >}} + +1. Log in to the Admin Dashboard. +2. Navigate to Pages from the side bar menu. +3. Click Add and enter the following values: + +{{< img src="/img/dashboard/portal-management/enterprise-portal/add-a-content-page-using-an-existing-template.png" alt="Add a new content page" >}} + +### Create a New Page + +#### Create the Layout File + +A layout behaves like a component that can be reused to inject templates in order to avoid duplicating elements such as `<head>` and `<link>`.So let’s create one that looks like the one below. + +1. From the file system navigate to `/themes/default/layouts`. +2. Create a new file named `my_layout.tmpl`. +3. Copy the code below, paste it to your new layout file and save it. + +```html +<!DOCTYPE html> +<html lang="en"> + + <head> + + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + <meta name="description" content=""> + <meta name="author" content=""> + + <title>{{ if .page}} {{.page.Title}} {{else}} Developer Portal {{end}} + + + + + + + + + + {{ render "top_nav" . }} +
+ + {{ yield }} +
+ + + {{ render "footer" . }} + + + + +``` +{{< note success >}} +**Note** + +The above snippet is taking into account the default developer portal setup, directories and references of the appropriate styling files. + +{{< /note >}} + +We have also added the top and footer navigation menus for demonstration purposes, `{{ render "top_nav" . }}` and `{{ render "footer" . }}` respectively. + +#### Create the Template File + +{{< note success >}} +**Note** + +Only follow this step after creating a new template file in Section 1 above, unless you want to use an existing template. + +{{< /note >}} + +1. From the file system; navigate to `/themes/default/views`. +2. Create a new file (template) +3. In this example, we will keep it simple and create a couple of HTML tags. Copy and paste the following code: + +```go +
+

{{ .page.Title }}

+

{{ .blocks.Description.Content }}

+
+``` +In this example, we use the code references in the template: +- Inside the template’s `

` we use `{{ .page.Title }}` to display the page name. +- Inside the template’s `

` we use `{{ .blocks.Description.Content }}` to display the page content. + +4. Name this `my_template.tmpl` and save it. +5. You now need to reference your new layout and template. From your Manifest file (`themes.json`) add a new key to the object that will look like this: + +```json +{ + "name": "My new Template", + "template": "my_template", + "layout": "my_layout" +} +``` +Alternatively, you can give it your preferred name but reference the template and layout names we created earlier in the manifest file. + +6. Now restart your developer portal service and go through the tutorial on how to add a new page. The template dropdown within the add new page form should have a new entry called `My new Template`, so create a page that will look like this: + +{{< img src="/img/dashboard/portal-management/enterprise-portal/add-page-details.png" alt="Add new page details" >}} + +7. Now navigate to the path we have entered on your browser (`my-domain.io/my-first-page`) and you should be able to see your new page with the content added via the UI: + +{{< img src="/img/dashboard/portal-management/enterprise-portal/my-first-page-example.png" alt="Example new UI page" >}} + +Taking as a scenario our above example, let’s see a visual explaining the correlation between the different files and UI. + +{{< img src="/img/dashboard/portal-management/enterprise-portal/scenario-correlation-diagram.png" alt="Scenario correlation" >}} + + +### Edit Page Content + +Content managers or similar roles that are responsible for the content displayed on the developer portal can edit and manage pages within the **Page section** of the Developer Portal. + +**Prerequisites** + +- Install the Developer portal +- Log in to the portal dashboard +- Default pages available or a page created by a developer which has the custom theme linked to it + +#### Instructions + +1. From the Pages section, open an existing page. This could be a page based on the default template or a new page that one of your developers set up when creating a new custom template. +2. Edit the page meta data. Change the name of the page if needed. Set or change the path URL if needed. + +{{< img src="/img/dashboard/portal-management/enterprise-portal/page-content-edit.png" alt="Edit Portal page content" >}} + +3. Edit the page content within the existing content blocks. + +{{< note success >}} +**Note** + +The content block name is linked to the content block name in the template html file. If this name is changed, and not reflected in the template html, the page will get an error and won’t show. + +{{< /note >}} + +4. Publish the page and view it from the external portal URL. If you want the page to be published and visible on the external portal, you need to change the state to Published. + + + +## Configure Menus + +The Developer portal has two types of menus: +1. The main navigation at the top (in the header) +2. The footer at the bottom. + +Both of them are defined as [partials]({{< ref "tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/file-structure-concepts" >}}) in the portal directory in `/themes/default/partials/`. + +### Top Navigation Menu + +The Enterprise Developer portal enables admin users to customize the navigation menu that appears on the top navigational bar of the live portal. An admin user can create and manage menu items without any code from the admin dashboard of the Developer portal. +{{< img src="img/dashboard/portal-management/enterprise-portal/top-nav-menu.png" alt="The navigation menu" >}} + +Each menu item may: +- lead to a specific page or URL: + {{< img src="img/dashboard/portal-management/enterprise-portal/regular-menu-item.png" alt="Regular menu item" >}} +- show a dropdown list with possible navigational options: + {{< img src="img/dashboard/portal-management/enterprise-portal/dropdown-menu-item.png" alt="Dropdown menu item" >}} + +Admin users can create additional navigational menus and render them on any page of the live portal. This customization requires changes to a theme and is covered in the [Full customization section]({{< ref "/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/menus-customisation.md" >}}). + +#### Manage Menu Items + +The management of the menu items is done from the **Menus** section of the Developer portal. + +1. Open the admin dashboard. Navigate to the **Menus** section. + {{< img src="img/dashboard/portal-management/enterprise-portal/navigation-to-menus-section.png" alt="Navigate to the Menus section" >}} + +2. Select a menu that you want to modify. By default, the Developer portal has only one **Primary** menu. If you want to add more menus and render them on the live portal, please refer to [Full customization section]({{< ref "/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/menus-customisation.md" >}}). + {{< img src="img/dashboard/portal-management/enterprise-portal/select-a-menu.png" alt="Select a menu" >}} + +3. Click on a **menu item** to modify it. You can change the following items: + 1. **Title** that will be exposed to developers. + 2. **Path** where developers will be redirected by clicking on that menu item. + 3. **Children** items that will be exposed in the dropdown list that will appear when hovering mouse over the menu item. + 4. To make the changes effectively, you need to save the changes by clicking on the **Save changes** button. + {{< img src="img/dashboard/portal-management/enterprise-portal/menu-item.png" alt="Modify a menu item" >}} + +4. To remove a menu item from the menu click on the **bin** icon and click on the **Save changes** button. + {{< img src="img/dashboard/portal-management/enterprise-portal/delete-a-menu-item.png" alt="Delete a menu item" >}} + +#### Create New Menu Items +To create a new menu item, you need to: + +1. Click on the **Add Menu Item** button. +2. Fill **Title**, **Path**, and **Children** fields. Save the changes by clicking on the **Save changes** button. + {{< img src="img/dashboard/portal-management/enterprise-portal/save-new-menu-item.png" alt="Save a menu item" >}} + +The new menu item will appear on the live portal immediately. +{{< img src="img/dashboard/portal-management/enterprise-portal/new-menu-item-on-the-live-portal.png" alt="New menu item on the live portal" >}}s + +#### Update Existing Menus + +1. Log into your portal +2. Select **Menus** from the navigation menu +3. Click **Primary** to edit the menu + +{{< img src="/img/dashboard/portal-management/enterprise-portal/edit-menu.png" alt="Edit Menu dialog" >}} + +**Field Descriptions** + +- **Name**: You can give it any name you like, it does not have any effect in the live portal nor the admin app. +- **Path**: This will be used in the code as a reference in order to render the menu. If you don’t have access to the template files, we recommend that you do not edit this field. Editing the `Path` for the default menus will hide the menu as there will be a mismatch between the Path and the reference in the template. +- **Menu Items**: + 1. **Title**: This will be the text that will be displayed in the live portal. + 2. **Path**: this is where the user will be redirected to. + 3. **Children**: In this section you add another nested menu item. We have added a dummy item (Product 1) to demonstrate + +Below is the menu item from its own view, which is available from the **Menu Items** option in the admin app side menu. + +{{< img src="/img/dashboard/portal-management/enterprise-portal/edit-menu-item.png" alt="Edit Menu item dialog" >}} + +Here's the menu as displayed in the app: + +{{< img src="/img/dashboard/portal-management/enterprise-portal/portal-menu-live.png" alt="Live menu in app" >}} + +We have mentioned above the relationship between a menu’s `Path` and the code reference in the menu template. Let’s see how the main menu template looks like (the file is `/themes/default/partials/` directory and is called `top_nav.tmpl`) for the part that we are interested in: + +```go +{{ if GetMenus.Primary }} + {{ range GetMenus.Primary.Children }} +

+ {{ end }} +{{ end }} +``` +Let's pick each line that is used to render the menu attributes and see how they work: + +1. `{{ if GetMenus.Primary }}`: This statement calls the “GetMenus” function and checks if there is a menu called `Primary`. If present, it goes into the next line: +2. `{{ range GetMenus.Primary.Children }}` Each Menu (Primary) has some children (Menu items) so what this code does is loop through all the children and they are rendered as below: + +```go + - {{ end }} - {{ end }} -{{ end }} -``` - -### GetProducts - -Returns the list of products for the current user. Expects the request as an argument. - -#### Product Attributes - -Accessible via `{{ range $product := GetProducts req }}` - -| Attribute | Description | -|-----------|-------------| -| `{{ $product.ID }}` | Product ID | -| `{{ $product.Name }}` | Product name | -| `{{ $product.DisplayName }}` | Product display name | -| `{{ $product.Path }}` | Product path | -| `{{ $product.ReferenceID }}` | Product reference ID | -| `{{ $product.Description }}` | Product description | -| `{{ $product.AuthType }}` | Product auth type | -| `{{ $product.Scopes }}` | Product scopes | -| `{{ $product.Logo.URL }}` | Product logo URL | -| `{{ $product.Feature }}` | true if the product is featured | -| `{{ $product.DCREnabled }}` | true if DCR is enabled | -| `{{ $product.ProviderID }}` | Provider ID | -| `{{ $product.APIDetails }}` | Array of API details associated with the product | -| `{{ $product.Catalogues }}` | Array of catalogues associated with the product | - -#### API Details Attributes (Within product) - -Accessible via `{{ range $api := $product.APIDetails }}` - -| Attribute | Description | -|-----------|-------------| -| `{{ $api.Name }}` | API name | -| `{{ $api.Description }}` | API description | -| `{{ $api.APIType }}` | API type | -| `{{ $api.TargetURL }}` | API target URL | -| `{{ $api.ListenPath }}` | API listen path | -| `{{ $api.OASUrl }}` | API OAS URL | -| `{{ $api.Status }}` | "Active" if API status is active, otherwise "Inactive" | - -#### Catalogue Attributes (Within product) - -Accessible via `{{ range $catalogue := $product.Catalogues }}` - -| Attribute | Description | -|-----------|-------------| -| `{{ $catalogue.Name }}` | Catalogue name | -| `{{ $catalogue.VisibilityStatus }}` | Catalogue visibility status | - -
- Example Usage - -```html -{{ range GetProducts req }} -
-
- {{ if .Logo.URL }} - - {{ end }} -
-
-
- {{ .AuthType }} -
-

{{ .ProductName }}

-
- {{ if .Description }} -

{{ .Description }}

- {{ end }} -
-
-
- More Info -
-
-
-
-{{ end }} -``` - -
- -### IsPortalDisabled - -Returns true (exception: for admins is always enabled) if portal visibility was set to hidden. Expects the request as -parameter. - -#### Example Usage -``` -{{ $portalDisabled := IsPortalDisabled req }} -``` - -### IsPortalPrivate - -Returns true (exception: for admins is always enabled) if portal visibility was set to private. Expects the request as -parameter. - -#### Example Usage -``` -{{ $portalPrivate := IsPortalPrivate req }} -``` - -### ProductDocRenderer - -Returns the configured product OAS renderer (redoc or stoplight). - -#### Example Usage -``` -{{ $oas_template := ProductDocRenderer }} -``` - -### ProviderUpstreamURL - -Returns the provider upstream URL for a given providerID. Expects the request and a provider ID as parameters. - -#### Example Usage -``` -{{ $upstreamURL := ProviderUpstreamURL req $thisProduct.ProviderID }} -``` - -### SplitStrings - -Splits a given string with given separator and returns a slice of split strings. - -#### Example Usage -``` -{{ range $app.Credentials }} -... -{{ range SplitStrings .GrantType "," }} -... -{{ end }} -{{ end }} -``` - -### TruncateString - -Truncates a given string to a given length, returning the truncated string followed by three dots (…). - -#### Example Usage -``` -{{ TruncateString $api.Description 60 }} -``` - -### TypeOfCredential - -Returns the credential type ("oAuth2.0" or "authToken") given the credential. - -#### Example Usage -``` -{{ range $app.Credentials }} -... -{{ if eq (TypeOfCredential . ) "oAuth2.0" }} -... -{{ end }} -{{end}} -``` - - -# Email Templates - -This section provides a detailed overview of the email template data available in the Tyk Enterprise Developer Portal. -The Tyk Enterprise Developer Portal uses a variety of email templates for different purposes, such as user registration -and access request status or organization status updates. Each template has access to specific data or functions relevant -to its purpose. - -It's important to note that while email templates can include template data or specific template functions, they do not -have access to the global helper functions available in other portal templates. - -Please refer to [email workflow]({{< ref "/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/full-customisation/email-customization" >}}) -for additional detail on email notifications sent by the portal. - - -## Available Email Templates - -- [Access Request Approve/Reject](#access-request-approvereject) -- [Access Request Submitted](#access-request-submitted) -- [Activate and Deactivate](#activate-and-deactivate) -- [New User Request](#new-user-request) -- [Organization Approve](#organization-approve) -- [Organization Reject](#organization-reject) -- [Organization Request](#organization-request) -- [Reset Password](#reset-password) -- [Targeted Invite](#targeted-invite) -- [Welcome User](#welcome-user) - -### Access Request Approve/Reject - -**Template Paths**: -- `themes/default/mailers/approve.tmpl` -- `themes/default/mailers/reject.tmpl` - -These templates are used for sending notifications to users when their access requests are approved or rejected. - -#### Available Objects - -There's no data sent to these templates. - -#### Example Usage -``` -Hi, -The API Credentials you provisioned have been rejected. -Thanks, -The Team -``` - -### Access Request Submitted - -**Template Path**: `themes/default/mailers/submitted.tmpl` - -This template is used for notifying administrators about pending access requests. - -#### Available Objects - -- `{{ .requests }}`: Returns the list of access requests pending approval. - -#### Access Request Attributes - -Accessible via `{{ range .requests }}` - -| Attribute | Description | -|-----------|-------------| -| `{{ .PlanID }}` | Plan ID associated with access request | -| `{{ .Status }}` | Request status | -| `{{ .AuthType }}` | Request authentication type | -| `{{ .UserID }}` | User ID associated with the request | -| `{{ .ClientID }}` | Client ID associated with the request | -| `{{ .DCREnabled }}` | Indicates if DCR (Dynamic Client Registration) is enabled for the request | -| `{{ .ProvisionImmediately }}` | Indicates if provisioning is immediate for the request | -| `{{ .CatalogueID }}` | Catalogue ID associated with the request | - -#### Product Attributes (within Access Request) - -Accessible via `{{ range $product := $acreq.Products }}` - -| Attribute | Description | -|-----------|-------------| -| `{{ $product.ID }}` | Product ID | -| `{{ $product.Name }}` | Product name | -| `{{ $product.DisplayName }}` | Product display name | -| `{{ $product.Description }}` | Product description | -| `{{ $product.AuthType }}` | Product authentication type | -| `{{ $product.DCREnabled }}` | Indicates if DCR (Dynamic Client Registration) is enabled for the product | - -#### Example Usage -```html -

A new Access request has been submitted. Please log in to the administration dashboard to view the request.

-
    - {{ range $acreq := .requests }} -
  • - Status: {{ $acreq.Status }}
    - User ID: {{ $acreq.UserID }}
    - Products: -
      - {{ range $product := $acreq.Products }} -
    • {{ $product.DisplayName }} ({{ $product.AuthType }})
    • - {{ end }} -
    -
  • - {{ end }} -
-``` - - -### Activate and Deactivate - -**Template Paths**: -- `themes/default/mailers/activate.tmpl` -- `themes/default/mailers/deactivate.tmpl` - -These templates are used for sending activation and deactivation notifications to users. - -#### Available Objects - -- `{{ .name }}`: Returns the user's full name. - -#### Example Usage -``` -Hi, {{.name}}
-Your account has been activated. -``` - -### New User Request - -**Template Path**: `themes/default/mailers/newuser.tmpl` - -This template is used for notifying administrators about new user registration requests pending activation. - -#### Available Objects - -- `{{ .user }}`: Returns the new user pending activation. - -### User Attributes - -Accessible via `{{ .user }}` - -| Attribute/Method | Description | -|-------------------|-------------| -| `{{ .ID }}` | User ID | -| `{{ .First }}` | User name | -| `{{ .Last }}` | User surname | -| `{{ .Email }}` | User email | -| `{{ .OrganisationID }}` | User organization ID | -| `{{ .DisplayName }}` | User complete name | -| `{{ .IdentityProvider }}` | User provider (Portal or Tyk Identity Broker) | -| `{{ .GetOrganisationID }}` | User's organization ID | -| `{{ .IsAdmin }}` | true if user is an admin | -| `{{ .IsOrgAdmin }}` | true if user is an organization admin | -| `{{ .DisplayRole }}` | User's role | -| `{{ .Organisation.Name }}` | Organization name | -| `{{ .Teams }}` | Array of user teams | -| `{{ .Teams.ID }}` | Team ID | -| `{{ .Teams.Name }}` | Team name | -| `{{ .Teams.Default }}` | Indicates if the team is the default team (true/false) | - -#### Example Usage -``` -

There is a new user request pending. Please approve it from the admin console.

-

- Id: {{ .user.ID }}
- User: {{ .user.DisplayName }} ({{ .user.Email }})
- Role: {{ .user.Role }}
- {{ if gt .user.OrganisationID 0 }} - Organisation: {{ .user.Organisation.Name }}
- {{ else }} - Organisation: Administrators' organisation
- {{ end }} - {{ if gt (len .user.Teams) 0 }} - Teams:
-

    - {{ range .user.Teams }} -
  • {{ .Name }}
  • - {{ end }} -
- {{ else }} - Teams: none - {{ end }} -

-``` - -### Organization Approve - -**Template Path**: `themes/default/mailers/organisation_request.tmpl` - -This template is used for notifying users that their organization creation request has been approved. - -#### Available Objects - -- `{{ site }}`: Returns the application host. - -#### Example Usage -``` -Hello, -The organization registration request has been approved. You can now manage your organization in your dashboard here: https://{{.site}}/portal/private/dashboard -Thanks, -The team -``` - -### Organization Reject - -**Template Path**: `themes/default/mailers/organisation_reject.tmpl` - -This template is used for notifying users that their organization creation request has been rejected. - -#### Available Objects - -There's no data sent to this template. - -#### Example Usage -``` -Hello, -The organization registration request has been rejected. -Thanks, -The team -``` - -### Organization Request - -**Template Path**: `themes/default/mailers/organisation_request.tmpl` - -This template is used for notifying administrators about new organization creation requests. - -#### Available Objects - -- `{{ .user }}`: Returns the user who made the request. -- `{{ .organisationName }}`: Returns the new organization name. - -### User Attributes - -Accessible via `{{ .user }}` - -| Attribute/Method | Description | -|-------------------|-------------| -| `{{ .ID }}` | User ID | -| `{{ .First }}` | User name | -| `{{ .Last }}` | User surname | -| `{{ .Email }}` | User email | -| `{{ .OrganisationID }}` | User organization ID | -| `{{ .DisplayName }}` | User complete name | -| `{{ .IdentityProvider }}` | User provider (Portal or Tyk Identity Broker) | -| `{{ .GetOrganisationID }}` | User's organization ID | -| `{{ .IsAdmin }}` | true if user is an admin | -| `{{ .IsOrgAdmin }}` | true if user is an organization admin | -| `{{ .DisplayRole }}` | User's role | - -#### Example Usage -``` -There is a new organization registration request pending. Please approve it from the admin console. -The organization name: {{ .organisationName }}. -The user: {{ .user.DisplayName }} ({{ .user.Email }}). -``` - -### Reset Password - -**Template Path**: `themes/default/mailers/auth/reset_password.tmpl` - -This template is used for sending password reset emails to users. - -#### Available Functions - -- `{{ current_user }}`: Returns the current user object. -- `{{ reset_password_url }}`: Returns the URL with the token for setting the password. - -#### User Attributes - -Accessible via `{{ current_user }}` - -| Attribute/Method | Description | -|-------------------|-------------| -| `{{ .ID }}` | User ID | -| `{{ .First }}` | User name | -| `{{ .Last }}` | User surname | -| `{{ .Email }}` | User email | -| `{{ .Role }}` | User role | -| `{{ .OrganisationID }}` | User organization ID | -| `{{ .DisplayName }}` | User complete name | -| `{{ .IdentityProvider }}` | User provider (Portal or Tyk Identity Broker) | -| `{{ .GetOrganisationID }}` | User's organization ID | -| `{{ .IsAdmin }}` | true if user is an admin | -| `{{ .IsOrgAdmin }}` | true if user is an organization admin | -| `{{ .DisplayRole }}` | User's role | - -#### Example Usage -``` -{{ $user := current_user}} -

Hello {{ $user.DisplayName }},

-

Someone has requested a link to change your password. You can do this through the link below.

-

{{reset_password_url}}

-

If you didn't request this, please ignore this email.

-

Your password won't change until you access the link above and create a new one.

-``` - -### Targeted Invite - -**Template Path**: `themes/default/mailers/auth/targeted_invite.tmpl` - -This template is used for sending targeted invitations to users. - -#### Available Functions - -- `{{ user }}`: Returns the targeted user object. -- `{{ team }}`: Returns the team name to which the user is being invited. -- `{{ invite_url }}`: Returns the URL with the token for setting the password. - -#### User Attributes - -Accessible via `{{ user }}` - -| Attribute/Method | Description | -|-------------------|-------------| -| `{{ .ID }}` | User ID | -| `{{ .First }}` | User name | -| `{{ .Last }}` | User surname | -| `{{ .Email }}` | User email | -| `{{ .Role }}` | User role | -| `{{ .OrganisationID }}` | User organization ID | -| `{{ .DisplayName }}` | User complete name | -| `{{ .IdentityProvider }}` | User provider (Portal or Tyk Identity Broker) | -| `{{ .GetOrganisationID }}` | User's organization ID | -| `{{ .IsAdmin }}` | true if user is an admin | -| `{{ .IsOrgAdmin }}` | true if user is an organization admin | -| `{{ .DisplayRole }}` | User's role | - -#### Example Usage -```html -{{ $u := user }} -Hi, {{ $u.DisplayName }}
-

Someone is inviting you to join {{ if $u.IsAdmin }}as an Administrator{{ else }}the {{ team }} team{{end }}. You can do this through the link below.

-

{{ invite_url }}

-

If you didn't request this, please ignore this email.

-``` - -### Welcome User - -**Template Paths**: -- `themes/default/mailers/welcome_admin.tmpl` -- `themes/default/mailers/welcome_dev.tmpl` - -These templates are used for sending welcome emails to new users, with separate templates for administrators and developers. - -#### Available Objects - -- `{{ .user }}`: Returns the user who made the request. Refer to the CurrentUser section for accessible attributes and methods. - -### User Attributes - -Accessible via `{{ .user }}` - -| Attribute/Method | Description | -|-------------------|-------------| -| `{{ .ID }}` | User ID | -| `{{ .First }}` | User name | -| `{{ .Last }}` | User surname | -| `{{ .Email }}` | User email | -| `{{ .OrganisationID }}` | User organization ID | -| `{{ .DisplayName }}` | User complete name | -| `{{ .IdentityProvider }}` | User provider (Portal or Tyk Identity Broker) | -| `{{ .GetOrganisationID }}` | User's organization ID | -| `{{ .IsAdmin }}` | true if user is an admin | -| `{{ .IsOrgAdmin }}` | true if user is an organization admin | -| `{{ .DisplayRole }}` | User's role | -| `{{ .Organisation.Name }}` | organization name | -| `{{ .Teams }}` | Array of user teams | -| `{{ .Teams.ID }}` | Team ID | -| `{{ .Teams.Name }}` | Team name | -| `{{ .Teams.Default }}` | Indicates if the team is the default team (true/false) | - -
- Example Usage - -```html -

Welcome to Tyk Enterprise Developer Portal

-

Hello {{ .user.DisplayName }},

-

Your account has been created for the {{ .user.Organisation.Name }} organisation.

-

Your assigned teams:

-
    - {{ range .user.Teams }} -
  • {{ .Name }}{{ if .Default }} (Default){{ end }}
  • - {{ end }} -
-

We're excited to have you on board!

-``` - -
\ No newline at end of file diff --git a/tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/quick-customisation.md b/tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/quick-customisation.md deleted file mode 100644 index dd8ccf4d08..0000000000 --- a/tyk-docs/content/tyk-stack/tyk-developer-portal/enterprise-developer-portal/customise-enterprise-portal/quick-customisation.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: "Quick Customization" -date: 2022-02-08 -tags: [""] -description: "" -menu: - main: - parent: "Customize the Enterprise Portal" -weight: 1 ---- - -{{< note success >}} -**Tyk Enterprise Developer Portal** - -If you are interested in getting access contact us at [support@tyk.io]() - -{{< /note >}} - -## Introduction - -In this section we will explain how to apply your branding (styling - CSS) on the portal elements with your own colors and logo within minutes. - -## Prerequisites - -- A Tyk Self-Managed [installation]({{< ref "/content/tyk-self-managed/install.md" >}}) -- A login for the portal admin app -- Access to your Tyk portal file system - -## Step by step instructions - -### Part 1 - Changing the portal logo - -1. Access the file directory for the Developer portal -2. The default logo is located in `/themes/default/assets/images/` and is called `dev-portal-logo.svg`. -3. Replace the default image with your own, keeping the same file name and in `.svg` format, ensuring that `xmlns="http://www.w3.org/2000/svg"` is included within your `` tag. - -{{< note success >}} -**Note** - -If you want to use different naming, path reference or extension, the code is `` and is found on line 6 from the `/themes/default/partials/footer.tmpl` template. -{{< /note >}} - -### Part 2 - Changing brand colors - -Let’s now explain how to manage borders and change the colors of buttons, texts and backgrounds. The file we’ll be looking at is `/themes/default/assets/stylesheets/main.css` which contains some CSS variables that are used throughout the app. Let’s take a closer look. -You can apply some changes in the portal based on your preferences. For example, you can change the navigation background color, the text color and the different button theme colors. Furthermore, you can change table border color and radius. - -If you want to change the navigation background color you need to edit the variable called `--tdp-nav-bg-color` Similarly other variables as you can see where/how each one is used: - -{{< note success >}} -**Note** - -`tdp` stands for Tyk Developer Portal - -{{< /note >}} - -#### Background colors - -{{< img src="/img/dashboard/portal-management/enterprise-portal/background-colors.png" alt="Background Colour settings Tyk Enterprise Portal" >}} - -- `--tdp-nav-bg-color` navigation background color -- `--tdp-body-bg-color` App background color - -#### Text colors - -{{< img src="/img/dashboard/portal-management/enterprise-portal/text-colors.png" alt="Text Colour settings Tyk Enterprise Portal" >}} - -- `--tdp-text-color` default text color -- `--tdp-link-color` links (anchor tags) -- `--tdp-nav-link-color` navigation links - -#### Borders - -{{< img src="/img/dashboard/portal-management/enterprise-portal/borders.png" alt="Border Colour settings Tyk Enterprise Portal" >}} - -- `--tdp-card-border-radius` Card component -- `--tdp-border-color-on-error` input color if there’s an error -- `--tdp-table-border-color` table -- `--tdp-border-radius` radius -- `--tdp-primary-border form` elements (such as `` and `` and `