Customize Core Pages

This article describes how to customize the core pages of API Portal.
apip50
This article describes how to customize the core pages of API Portal.
With the launch of API Hub in API Portal 5.0 as the console customization platform and the deprecation of the custom page resources (/custom/1.0/pages) in API Portal 5.0.2, Broadcom Layer7 will no longer make enhancements to Custom Pages. Use the API Hub for all developer console customization tasks as the choice alternative to serve your API consumers and developers.
2
2
What You Can Customize
You can fully customize the following core API Portal pages to provide your customers with a fully branded experience of the public page:
  • Home
  • Login
  • Sign Up
  • Account Setup
  • Reset Password
  • New Password
You can bundle your custom pages (and all the related files, for example, js and css) in a zip file. Upload this file to API Portal and apply the customization, instantly.
The
Content Management
menu provides an easy way to set your custom pages as the default. Your current home page is automatically listed as "default".
You can either use the templates provided in the Content Management page or use your own html content to apply the customization.
Use Templates for Customization
API Portal provides a set of templates for each of the core API Portal pages that you want to customize. Each template file contains the minimum content that is required to make the corresponding page work as expected. You can create your own custom pages by customizing the template files or by creating your own files from scratch. The templates are available in
SampleTemplates.zip
file that you have to download from
Content Management, Upload Page Bundles
section.
The zip file contains six html pages and folders containing corresponding js and css files. This zip also contains a common folder where you can put common resources like js and css files, which can be applied across all pages.
Templates ensure easier and faster customization.
The template file works similar to the default API Portal page that you want to customize. Ensure that you understand the functionality before attempting to change the files. Random changes in the code might result in an unstable page.
Prerequisites for Customization
Verify the following prerequisites before customizing the core pages:
  • You have Tenant or Portal Administrator access in API Portal.
  • You are aware of the external authentication schemes that must be applied on the Login page.
  • You know that the permissible size limit for the zip file should not exceed 15 MB.
  • The following file types are supported:
    • png
    • jpg
    • jpeg
    • gif
    • ico
    • svg
    • html
    • css
    • js
    • ttf
    • woff
    • woff2
    • otf
  • File names (including the zip file) should only contain alphanumeric characters, underscores, spaces, and hyphens.
  • You have experience in coding and consuming the APIs. Read the APIs that are applicable for the page you want to customize. The following table lists the minimum APIs that you can consume to make the pages work as expected:
    Page
    APIs
    Description
    Login
    /api/{tenantId}/authenticate/login
    To authenticate users using API Portal, call the POST method on this API with payload containing user credentials.
    /admin/public/auth/schemes
    Provides a list of authentication schemes available for the tenant. These authentication schemes are displayed in the Login page.
    "/api/{tenantId}/authenticate/getPublicKey
    'If the API returns the public key, then the password has to be encrypted in the "/api/{tenantId}/authenticate/login" payload.'
    Sign Up
    /admin/Portal.svc/Registrations
    To place a sign-up request, call POST method on this API with payload containing user information.
    Account Setup
    /admin/accountSetup
    Account Setup page is loaded with a token as a query parameter, which is required for setting up the account. To validate the token, call GET method on this API with token as query parameter.
    /api/{tenantId}/authenticate/getPublicKey
    If the API returns the public key, then the password has to be encrypted in the "/admin/accountSetup" payload.
    /admin/accountSetup
    To complete the account setup process, call PUT method on this API with payload containing user information, password, and token.
    Reset Password
    /admin/Portal.svc/ResetMyPassword()
    To place a request to update the password, call GET method on this API with username as query parameter.
    New Password
    /admin/passwordResetTokenValidate
    This page is loaded with a token as path parameter, which is required in the password reset process. The token can be validated by calling GET method on this API with token as query parameter.
    /api/{tenantId}/authenticate/getPublicKey
    If the API returns the public key, then encrypt the password in the "/admin/UpdateMyPassword" payload.
    /admin/UpdateMyPassword
    To complete the reset password process, call POST method on this API with payload containing password and token.
APIs to Create Custom Pages
Ensure you are aware of the APIs required to make the custom pages work, as expected.
For example, to customize the Login page, you need text boxes for entering the username and password, display the authorization schemes (portal, LDAP, SAML, and so on), and a
Login
button. The user must select an authorization scheme, and then enter the credentials. When the user clicks
Login
, API Portal calls an API to validate the user credentials.
The following Swagger representation is created from a static JSON file.
{ "swagger": "2.0", "info": { "version": "1.0.0", "title": "CA Customize Portal Pages" }, "host": "apim.dev.ca.com", "basePath": "/", "tags": [ { "name": "Login", "description": "" }, { "name": "Reset Password", "description": "" }, { "name": "Sign Up", "description": "" }, { "name": "Home", "description": "" }, { "name": "Account Setup", "description": "" }, { "name": "New Password", "description": "" }, { "name": "Common APIs", "description": "" } ], "schemes": [ "https" ], "paths": { "/api/{tenantId}/branding/1.0/themes": { "get": { "tags": [ "Common APIs" ], "summary": "Fetch Theme Settings", "description": "Returns the settings for the applied theme on the tenant.", "operationId": "getTheme", "produces": [ "application/json" ], "parameters": [ { "$ref": "#/parameters/tenantParam" } ], "responses": { "200": { "description": "Theme related settings.", "schema": { "$ref": "#/definitions/ThemesSettings" } } } } }, "/admin/public/auth/schemes": { "get": { "tags": [ "Login" ], "summary": "Fetch the available Authentication Schemes", "description": "Fetch the available Authentication Schemes along with Public Key which would be used for encrypting login password if Enhanced Security is enabled for default APIM auth scheme or LDAP auth schemes.", "operationId": "getAuthSchemes", "produces": [ "application/json" ], "responses": { "200": { "description": "Success", "schema": { "$ref": "#/definitions/AuthSchemes" } } } } }, "/api/{tenantId}/authenticate/login": { "post": { "tags": [ "Login" ], "summary": "Login API", "description": "Used for authenticating the user.<br>When Enhanced Security is enabled /admin/public/auth/schemes will return publicKey which should be used to encrypt the password and passed as header.", "operationId": "submitLoginForm", "consumes": [ "application/json" ], "produces": [ "application/json" ], "parameters": [ { "$ref": "#/parameters/publicKeyHeader" }, { "$ref": "#/parameters/tenantParam" }, { "$ref": "#/parameters/LoginParam" } ], "responses": { "200": { "description": "Success", "schema": { "$ref": "#/definitions/LoginResponse" } }, "400": { "description": "Bad Request" }, "401": { "description": "Unauthorized" }, "500": { "description": "Internal Server Error" } } } }, "/admin/Portal.svc/Registrations": { "post": { "tags": [ "Sign Up" ], "summary": "Submit registration request", "description": "Used to signup a new user.", "operationId": "submitSignUpForm", "consumes": [ "application/json" ], "produces": [ "application/json" ], "parameters": [ { "$ref": "#/parameters/SignUpParam" } ], "responses": { "200": { "description": "OK", "schema": { "$ref": "#/definitions/SignUpResponse" } }, "400": { "description": "Bad Request" }, "500": { "description": "Internal Server Error", "schema": { "$ref": "#/definitions/Error" } } } } }, "/admin/navigation": { "get": { "tags": [ "Home" ], "summary": "Fetch the navigation list", "description": "", "produces": [ "application/json" ], "responses": { "200": { "description": "Success", "schema": { "$ref": "#/definitions/Navigation" } } } } }, "/admin/public/auth/schemes/passwordPolicies": { "get": { "tags": [ "Common APIs" ], "summary": "Fetch password policies for the tenant", "description": "Fetch password policy when Activating user or Resetting user password, a set of rules user password must adhere.", "produces": [ "application/json" ], "responses": { "200": { "description": "Success", "schema": { "$ref": "#/definitions/PasswordPolicies" } } } } }, "/api/{tenantId}/authenticate/getPublicKey": { "get": { "summary": "Fetch public key for password encryption", "description": "Fetch public key which would be used for encrypting user password when Activating User or Resetting Password if Enhanced Security is enabled.", "produces": [ "application/json" ], "tags": [ "Common APIs" ], "parameters": [ { "$ref": "#/parameters/tenantParam" } ], "responses": { "200": { "description": "Success", "schema": { "type": "object", "properties": { "respCode": { "type": "integer" }, "respMsg": { "type": "string" }, "publicKey": { "type": "string" } }, "example": { "respCode": 200, "respMsg": "Successfully fetched public key", "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAocaSLKk9v2BVYEDDN2jXmFn9ygnjeUYIs+aFNF8KLsI+l9cE3TcLWo" } } } } } }, "/admin/UpdateMyPassword": { "post": { "summary": "Reset the password of an existing user", "produces": [ "application/json" ], "tags": [ "New Password" ], "description": "API to reset password.<br>When Enhanced Security is enabled /api/{tenantId}/authenticate/getPublicKey will return publicKey which should be used to encrypt the password and passed as header.", "parameters": [ { "$ref": "#/parameters/publicKeyHeader" }, { "in": "body", "name": "password", "description": "The fields required to reset password.", "schema": { "type": "object", "required": [ "passwordDetails" ], "properties": { "password": { "type": "string" }, "token": { "type": "string" }, "Uuid": { "type": "string" } }, "example": { "password": "[email protected]", "token": "MDVhMGM0ZDItNmQwNS00YWNjLTk0OGUtNmZkZWIwMzhjMTlh", "Uuid": "{{GENERATED_GUID}}" } } } ], "responses": { "200": { "description": "Successful update" }, "400": { "description": "Bad Request" }, "500": { "description": "Internal Server Error" } } } }, "/admin/accountSetup": { "put": { "summary": "Activate user account", "produces": [ "application/json" ], "tags": [ "Account Setup" ], "description": "API to complete account setup.<br>When Enhanced Security is enabled /api/{tenantId}/authenticate/getPublicKey will return publicKey which should be used to encrypt the password and passed as header.", "parameters": [ { "$ref": "#/parameters/publicKeyHeader" }, { "in": "query", "name": "authenticity-token", "type": "string" }, { "in": "body", "name": "AccountSetup", "schema": { "type": "object", "properties": { "token": { "type": "string" }, "uuid": { "type": "string" }, "firstName": { "type": "string" }, "lastName": { "type": "string" }, "email": { "type": "string" }, "userName": { "type": "string" }, "password": { "type": "string" } }, "example": { "token": "MDVhMGM0ZDItNmQwNS00YWNjLTk0OGUtNmZkZWIwMzhjMTlh", "Uuid": "{{GENERATED_GUID}}", "firstName": "First", "lastName": "Last", "email": "[email protected]", "userName": "admin", "password": "[email protected]" } } } ], "responses": { "200": { "description": "Success" }, "400": { "description": "Bad Request" }, "500": { "description": "Internal Server Error" } } }, "get": { "summary": "Validate activation token", "description": "For checking if activation token is valid or not.", "produces": [ "application/json" ], "tags": [ "Account Setup" ], "parameters": [ { "in": "query", "name": "token", "type": "string" } ], "responses": { "200": { "description": "Success" } } } }, "/admin/Portal.svc/ResetMyPassword()": { "get": { "summary": "Initiate password reset for a user", "description": "On submitting username an email is sent to user for resetting the password.", "produces": [ "application/json" ], "tags": [ "Reset Password" ], "parameters": [ { "in": "query", "name": "Username", "type": "string" } ], "responses": { "200": { "description": "Success", "schema": { "$ref": "#/definitions/ResultResponse" } } } } }, "/admin/passwordResetTokenValidate": { "get": { "summary": "Validate password reset token", "description": "For checking if password reset token is valid or not.", "produces": [ "boolean" ], "tags": [ "New Password" ], "parameters": [ { "in": "query", "name": "token", "type": "string" } ], "responses": { "200": { "description": "Success", "schema": { "type": "boolean", "example": true } } } } }, "/admin/Portal.svc/UserNameUnique()": { "get": { "summary": "Username unique check", "description": "For validating if username is unique or not.", "produces": [ "application/json" ], "tags": [ "Account Setup" ], "parameters": [ { "in": "query", "name": "Name", "type": "string", "description": "Apply encodeURIComponent on name before sending" } ], "responses": { "200": { "description": "Success", "schema": { "$ref": "#/definitions/ResultResponse" } } } } }, "/admin/sessionCheck": { "get": { "summary": "User session check", "description": "For validating if user is loggedIn or not.", "produces": [ "application/json" ], "tags": [ "Common APIs" ], "responses": { "200": { "description": "Success", "schema": { "type": "object", "properties": { "status": { "type": "boolean" } }, "example": { "status": true } } } } } }, "/admin/Portal.svc/OrganizationNameUnique()": { "get": { "summary": "Username unique check", "description": "For validating if username is unique or not.", "produces": [ "application/json" ], "tags": [ "Reset Password" ], "parameters": [ { "in": "query", "name": "Name", "type": "string", "description": "Apply encodeURIComponent on name before sending" } ], "responses": { "200": { "description": "Success", "schema": { "$ref": "#/definitions/ResultResponse" } } } } } }, "parameters": { "publicKeyHeader": { "name": "publicKey", "in": "header", "description": "an encryption key", "required": false, "type": "string" }, "tenantParam": { "name": "tenantId", "in": "path", "description": "ID of tenant", "required": true, "type": "string", "x-example": "apim" }, "LoginParam": { "name": "body", "in": "body", "description": "Login parameters", "required": true, "schema": { "$ref": "#/definitions/LoginRequest" } }, "SignUpParam": { "name": "body", "in": "body", "description": "SignUp parameters", "required": true, "schema": { "$ref": "#/definitions/SignUpRequest" } } }, "definitions": { "BaseResponse": { "type": "object", "properties": { "respCode": { "type": "string" }, "respMsg": { "type": "string" } } }, "BaseResponseInteger": { "type": "object", "properties": { "respCode": { "type": "integer" }, "respMsg": { "type": "string" } } }, "AuthSchemes": { "allOf": [ { "$ref": "#/definitions/BaseResponseInteger" } ], "type": "object", "properties": { "authSchemes": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "description": { "type": "string" }, "authMethod": { "type": "string" }, "editable": { "type": "boolean" }, "showFyp": { "type": "boolean" }, "credsReqd": { "type": "boolean" }, "defaultConfig": { "type": "boolean" }, "url": { "type": "string" }, "advancedConfigurations": { "type": "object", "properties": { "enhancedPasswordSecurity": { "type": "string" } } } } } }, "publicKey": { "type": "string" } }, "example": { "respCode": 200, "respMsg": "Successfully fetched Authentication Schemes", "authSchemes": [ { "uuid": "479c0a44-7f9d-42cf-b778-fbdb2e04e1a9", "name": "CA Technologies Developer Network", "description": "", "authMethod": "DEFAULT", "editable": true, "showFyp": true, "credsReqd": true, "defaultConfig": true, "url": "http://apim.dev.ca.com/admin/login", "advancedConfigurations": { "enhancedPasswordSecurity": "no" } } ], "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz5OfFKwJaCSjfPDP9DfSp4+4t9MkWqngRbUsviRFcBH9Ko6SNGNWzZlOeASZnukdxShnCueR6UcMvKwx9dlUXL6nNalR9k7OE4IYAwi4xXpligsGc4LWW+3AEkR9v4KaId1zD5Dhhcbw7BohUztHmV0zpGk0dzmstRR2sxMhjinXUpiK0xK3YGsOtBWgVxc9NHJwYJ0flHLWytp5SbJ6Kzx2LaJF2AZrGpQyMBhSV5TUJ45Dxw/UUUZvdBjrcwzWgq8QR5vmX5QjFfK+XN+O2K3oGmnyqxZ9anl87UxKu9AeD+i1ekWZrsH+khozBRhiUbNpHp8jO6CwpGRYNuSuAwIDAQAB" } }, "LoginResponse": { "allOf": [ { "$ref": "#/definitions/BaseResponse" } ], "type": "object", "properties": { "provider": { "type": "string" }, "referrer": { "type": "string" }, "dashboardPath": { "type": "string" } }, "example": { "respCode": "200", "respMsg": "Successfully authenticated user", "provider": "", "referrer": "", "dashboardPath": "" } }, "LoginRequest": { "type": "object", "properties": { "username": { "type": "string" }, "password": { "type": "string" }, "uuid": { "type": "string" }, "eula": { "type": "string" } }, "example": { "username": "admin", "password": "7layereyal7", "eula": "accept", "uuid": "{{GENERATED_GUID}}" } }, "ThemeBasic": { "description": "A representation of a Theme.", "type": "object", "properties": { "logo": { "type": "string", "description": "Base64 string of portal logo.", "maxLength": 716800 }, "favicon": { "type": "string", "description": "Base64 string of portal favicon.", "maxLength": 716800 }, "siteTitle": { "type": "string" }, "color": { "type": "object", "properties": { "siteTitle": { "type": "string" }, "pageTitle": { "type": "string" }, "background": { "type": "string" }, "bodyText": { "type": "string" }, "link": { "type": "string" }, "linkHover": { "type": "string" }, "smallText": { "type": "string" }, "borderColor": { "type": "string" }, "primaryButtonBackground": { "type": "string" }, "primaryButtonText": { "type": "string" }, "primaryButtonHover": { "type": "string" }, "headerBackground": { "type": "string" }, "headerLink": { "type": "string" }, "footerBackground": { "type": "string" }, "footerText": { "type": "string" }, "footerLink": { "type": "string" } } }, "typography": { "type": "object", "properties": { "siteTitle": { "type": "string" }, "pageTitle": { "type": "string" }, "bodyText": { "type": "string" }, "smallText": { "type": "string" }, "footerText": { "type": "string" }, "buttonText": { "type": "string" } } }, "fontSize": { "type": "object", "properties": { "siteTitle": { "type": "string" }, "pageTitle": { "type": "string" }, "bodyText": { "type": "string" }, "smallText": { "type": "string" }, "footerText": { "type": "string" }, "buttonText": { "type": "string" } } }, "display": { "type": "object", "properties": { "versionNumber": { "type": "boolean" }, "copyright": { "type": "boolean" } } }, "label": { "type": "object", "description": "Custom menu label.", "properties": { "service.publish.nav.manageapi.title": { "type": "string" }, "service.publish.nav.apps.title": { "type": "string" }, "service.publish.nav.apicatalog.title": { "type": "string" }, "service.publish.nav.apiexplorer.title": { "type": "string" } } } } }, "ThemeFontGetDto": { "type": "object", "properties": { "name": { "type": "string" }, "ttfUri": { "type": "string" }, "woffUri": { "type": "string" }, "woff2Uri": { "type": "string" }, "eotUri": { "type": "string" }, "otfUri": { "type": "string" } } }, "ThemesSettings": { "allOf": [ { "$ref": "#/definitions/ThemeBasic" } ], "type": "object", "properties": { "typography": { "type": "object", "properties": { "custom": { "type": "array", "items": { "$ref": "#/definitions/ThemeFontGetDto" } } } }, "images": { "type": "object", "properties": { "backgroundFooterUri": { "type": "string", "description": "Uri to background footer image" }, "backgroundHeaderUri": { "type": "string", "description": "Uri to background header image" } } } }, "example": { "logo": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAAA8CAYAAADFXvyQAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA/dpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ1dWlkOjkxNkRBMDU0MEIzOERGMTE4N0Y3RTdFRUFERUI2NUM0IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjkwRkI0NDgwRTJCRjExRTNCRjE1QTU2MzE5RTY4QTIzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjkwRkI0NDdGRTJCRjExRTNCRjE1QTU2MzE5RTY4QTIzIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIElsbHVzdHJhdG9yIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OGNkYTBiNTMtYjNjZC00YTcyLWIyY2ItZjA5ZjliYzRlOGExIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjhj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", "favicon": "data:image/vnd.microsoft.icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////+/v7//T09P/39/f///////7+/v/39/f/9fX1//39/f///////Pz8//z8/P/+/v7////////////5+fn/urq6/2tra/9NTU3/WFhY/6Kiov+goKD/V1dX/05OTv+Ghob/u7u7/3Fxcf9wcHD/wcHB/9PT0//8/Pz/l5eX/xUVFf8AAAD/AAAA/wsLC/9BQUH/Dg4O/wEBAf8cHBz/Hh4e/yEhIf8EBAT/EBAQ/7Ozs//g4OD/y8vL/yQkJP8AAAD/Hx8f/4aGhv+VlZX/Pj4+/wAAAP9AQED/1dXV/8bGxv8zMzP/AAAA/xEREf/ExMT//////4eHh/8FBQX/AAAA/3l5ef//////+fn5/15eXv8AAAD/QkJC/+Hh4f//////hoaG/wAAAP8RERH/xMTE//////9nZ2f/AAAA/wQEBP+cnJz///////////+9vb3/Kioq/wQEBP82Njb/e3t7/1ZWVv8AAAD/ERER/8TExP//////cXFx/wAAAP8EBAT/m5ub////////////+Pj4/8bGxv99fX3/UFBQ/zk5Of8eHh7/AAAA/xEREf/Dw8P//////6Kiov8MDAz/AAAA/21tbf/6+vr/8/Pz/39/f/9MTEz/hoaG/+np6f/t7e3/cXFx/wAAAP8RERH/xcXF///////n5+f/R0dH/wAAAP8TExP/ZWVl/2BgYP8NDQ3/BQUF/0VFRf9jY2P/b29v/x8fH/8AAAD/IyMj/9ra2v///////////83Nzf9HR0f/CwsL/wAAAP8AAAD/ERER/1tbW/9DQ0P/AgIC/wAAAP8DAwP/GBgY/4yMjP/7+/v/////////////////6urq/7Kysv+SkpL/lZWV/76+vv/w8PD/zc3N/56env+Pj4//mZmZ/8fHx//4+Pj/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", "siteTitle": "CA Technologies Developer Network", "lastUpdated": 1501784674317, "color": { "siteTitle": "#48575F", "pageTitle": "#48575F", "background": "#F7F7F7", "bodyText": "#48575F", "link": "#09AEEF", "linkHover": "rgba(9, 174, 239, .5)", "smallText": "#48575F", "borderColor": "#D8D8D8", "primaryButtonBackground": "#09AEEF", "primaryButtonText": "#FFFFFF", "primaryButtonHover": "rgba(9, 174, 239, .5)", "headerBackground": "#FFFFFF", "headerLink": "#09AEEF", "footerBackground": "#48575F", "footerText": "#FFFFFF", "footerLink": "#09AEEF" }, "typography": { "siteTitle": "CA Sans Light", "pageTitle": "CA Sans Light", "bodyText": "Clear Sans", "smallText": "Clear Sans", "footerText": "Clear Sans", "buttonText": "Clear Sans", "custom": [] }, "fontSize": { "siteTitle": "30px", "pageTitle": "25px", "bodyText": "14px", "smallText": "12px", "footerText": "14px", "buttonText": "16px" }, "display": { "versionNumber": true, "copyright": true }, "images": { "backgroundFooterUri": "", "backgroundHeaderUri": "" }, "label": { "service.publish.nav.manageapi.title": "APIs", "service.publish.nav.apps.title": "Apps", "service.publish.nav.apiexplorer.title": "API Explorer" } } }, "SignUpRequest": { "type": "object", "properties": { "Email": { "type": "string" }, "OrganizationName": { "type": "string", "description": "Should be unique" }, "OrganizationDescription": { "type": "string" }, "Uuid": { "type": "string" } }, "example": { "Email": "[email protected]", "OrganizationName": "QWdssdc", "OrganizationDescription": "", "Uuid": "{{GENERATED_GUID}}" } }, "SignUpResponse": { "type": "object", "properties": { "d": { "type": "object", "properties": { "__metadata": { "type": "object", "properties": { "uri": { "type": "string" }, "type": { "type": "string" } } }, "OrganizationName": { "type": "string" }, "Uuid": { "type": "string" }, "Email": { "type": "string" }, "FormField": { "type": "string" }, "OrganizationDescription": { "type": "string" } } } }, "example": { "d": { "__metadata": { "uri": "http://apim.dev.ca.com/portal-data/Portal.svc/Registrations('48ad61b0-87b1-4fae-bba1-73e5f3e48df8')", "type": "com.layer7.portal.service.odata.PortalODataProducerFactory.Registration" }, "OrganizationName": "QWdsdc", "Uuid": "48ad61b0-87b1-4fae-bba1-73e5f3e48df8", "Email": "[email protected]", "FormField": null, "OrganizationDescription": "" } } }, "Message": { "type": "object", "properties": { "lang": { "type": "string" }, "value": { "type": "string" } } }, "ErrorBody": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "$ref": "#/definitions/Message" } } }, "Error": { "type": "object", "properties": { "error": { "$ref": "#/definitions/ErrorBody" } }, "example": { "error": { "code": "ServerErrorException", "message": { "lang": "en-US", "value": "Internal Server Error" } } } }, "NavigationListBody": { "type": "object", "properties": { "url": { "type": "string" }, "title": { "type": "string" }, "titleKey": { "type": "string" }, "target": { "type": "string" } } }, "Navigation": { "type": "object", "properties": { "portalAdmin": { "type": "array", "items": { "$ref": "#/definitions/NavigationListBody" } }, "developer": { "type": "array", "items": { "$ref": "#/definitions/NavigationListBody" } }, "account": { "type": "array", "items": { "$ref": "#/definitions/NavigationListBody" } }, "hidden": { "type": "array", "items": { "$ref": "#/definitions/NavigationListBody" } } }, "example": { "portalAdmin": [ { "url": "/admin/app/api-catalog", "title": "API Catalog", "titleKey": "label.appnav.apicatalog", "target": null } ], "developer": [ { "url": "/admin/homeRedirect", "title": "Home", "titleKey": "label.appnav.home", "target": null } ], "account": [ { "url": "/admin/app/registration", "title": "Sign Up", "titleKey": "label.appnav.register", "target": null }, { "url": "/admin/loginRedirect", "title": "Login", "titleKey": "label.appnav.login", "target": null } ], "hidden": [] } }, "passwordPolicyElement": { "type": "object", "properties": { "value": { "type": "integer", "description": "value of the property" }, "enabled": { "type": "boolean", "description": "whether the property is enabled" } } }, "PasswordPolicies": { "allOf": [ { "$ref": "#/definitions/BaseResponseInteger" } ], "type": "object", "properties": { "authScheme": { "type": "object", "properties": { "passwordpolicies": { "type": "object", "properties": { "regexConfig": { "type": "object", "properties": { "MINIMUM_LENGTH": { "$ref": "#/definitions/passwordPolicyElement" }, "SYMBOL": { "$ref": "#/definitions/passwordPolicyElement" }, "NUMBER": { "$ref": "#/definitions/passwordPolicyElement" }, "REGEX": { "type": "object", "$ref": "#/definitions/passwordPolicyElement" }, "UPPERCASE": { "$ref": "#/definitions/passwordPolicyElement" }, "MAXIMUM_LENGTH": { "$ref": "#/definitions/passwordPolicyElement" }, "LOWERCASE": { "$ref": "#/definitions/passwordPolicyElement" }, "SUPPORTED_SYMBOLS": { "$ref": "#/definitions/passwordPolicyElement" } } }, "passwordConfig": { "type": "object", "properties": { "PASSWORD_HISTORY": { "$ref": "#/definitions/passwordPolicyElement" }, "PASSWORD_EXPIRY": { "$ref": "#/definitions/passwordPolicyElement" } } } } } } } }, "example": { "respCode": 200, "respMsg": "Successfully fetched Password Policies", "authScheme": { "passwordPolicies": { "regexConfig": { "MINIMUM_LENGTH": { "value": 8, "enabled": true }, "SYMBOL": { "value": 1, "enabled": true }, "NUMBER": { "value": 1, "enabled": true }, "REGEX": { "value": "^(?=(.*[a-z]){1})(?=(.*[[email protected]#$%^&*-]){1})(?=(.*[A-Z]){1})(?=(.*[0-9]){1})[ [email protected]#$%^&*-]{8,60}$", "enabled": true }, "UPPERCASE": { "value": 1, "enabled": true }, "MAXIMUM_LENGTH": { "value": 60, "enabled": true }, "LOWERCASE": { "value": 1, "enabled": true }, "SUPPORTED_SYMBOLS": { "value": "[email protected]#$%^&*-", "enabled": true } }, "passwordConfig": { "PASSWORD_HISTORY": { "value": 5, "enabled": false }, "PASSWORD_EXPIRY": { "value": 60, "enabled": false } } } } } }, "ResultResponse": { "type": "object", "properties": { "d": { "type": "object", "properties": { "result": { "type": "boolean" } } } }, "example": { "d": { "result": true } } } } }
Prerequisites for Re-customization
You do not need to remove an existing bundle to upload a new one. System allows you to upload another bundle, while the existing one is still in use. Consider the following points for re-customization:
  • You cannot upload more than two bundles. To add one more bundle, delete the bundle that is not in use.
  • Recommendation:
    Use a different html filename every time you apply the customization on the same page. For example, if you have used home.html for the initial customization, then use home1.html for the subsequent customization. This process ensures that the page caching is considerably improved and the changes are reflected faster.
  • Recommendation:
    Keep a backup of your previous customization, if necessary.
Start Customizing
  1. To use the templates, download and unzip "SampleTemplates.zip" from
    Content Management, Manage Custom Pages, Upload Page Bundles.
    1. Go to
      <PageName>
      .
      The folder contains the html, js, and css files.
    2. Depending on your organization's needs, customize the files. Read the APIs that are applicable for the page that you want to customize.
    3. Save your changes.
  2. Create a zip file with all the contents that you need for customization.
  3. From
    Upload Page Bundles
    , select
    Upload Select Upload ZIP Bundle
    to upload this zip file.
    If you have already uploaded two bundles, you have to delete an unpublished bundle to upload a new one.
  4. Select the html file from the
    <PageName>
    drop down. For example, if you are customizing the Home page, select the Home drop-down.
    All the assignments should be from a single bundle; pages from different bundles cannot be saved.
  5. Select
    Save & Publish
    . Selecting
    Cancel
    restores the previous customization, but the recently uploaded bundle remains in the Source Bundle drop down.
    Consider the following points after you have customized:
    • The bundle status changes to "Published" as shown in the following screenshot.
      Cust.png
    • You have selected a bundle, but assigned and saved all the pages to portal default. The selected bundle becomes unpublished.
    • The Delete Bundle link does not appear when you select a published bundle from the Source Bundle drop down.
Reset to Default Settings
Select
None
from Source Bundle drop down and save your changes. All the pages are reset to default portal pages and the published bundle becomes unpublished.
Delete a Bundle
You can only delete a bundle that is unpublished (not in use).
Follow these steps:
  1. Select the bundle that is not in use from
    Source Bundle
    .
  2. Select
    Delete Bundle
    .
  3. Select
    Delete
    .
FAQs
  • I have customized a page. How do I revert to the default page?
    You can select the "default" option from the drop-down.
  • To re-customize the pages, I uploaded a new bundle. I selected the pages from the drop-down. But I did not save the changes and navigated to another page. Will the older customization be retained?
    Yes. Customization does not change until you publish or save the changes. Similar applies when the Content Management page times out before you save the changes.
  • I customized a page using a file, but the changes are not reflecting immediately or are taking longer than expected. What do I do?
    This problem occurs because of caching. You may have used the same filename when reapplying the customization. The resources are updated, but the dispatcher still serves the old resources. It might take an hour to serve the updated content due to caching on dispatcher.
    To force the dispatcher to serve the updated content instantly, the Portal administrator can restart the dispatcher container.
    API Portal is unavailable while the dispatcher restarts.
    Now, when the dispatcher starts serving updated pages, you still might not see the updated content. This is because of web browser caching and might take a day to show the newer version. Clear the cached assets for the API Portal site or open the site in private or incognito mode.
  • I applied the changes to the Login page and I can see the customizations. But something went wrong in this page, because I am unable to relogin and fix the changes. How do I go back to the default Login page?
    This issue might have happened because you modified the
    main.js
    file incorrectly. Ensure that you read the APIs before attempting to change the code. To go back to default Login page, enter http://<portal.ca.com>/admin/login into your web browser.