Templates

Blackbeard includes a templating system that you can use to modify the layout and content of any page on your Portal. To add your templates: 0. Log in to the API Control Center. 0. To to `Manage > Portal` and click on `Portal Settings`. 0. Add your templates under the `Inline Javascript` section in the `Body JavaScript` field. ## Template Formats Templates can be simple JavaScript strings, or for more complex or logic-driven layouts, a function that returns a string. ```js // A template string portalOptions.templates.contact = '

This is a valid template.

'; // A template function portalOptions.templates.contact = function () { return '

This is, too!

'; }; ``` ## Placeholder Content Templates accept placeholder variables that are automatically replaced with content during the render process. ```js /** * Content * Placeholder variables for content. */ {{mashery.area}} // The name of your Portal as defined in Control Center. {{content.heading}} // The title of the page's H1 element, if one exists. {{content.main}} // The main content for the page. On custom pages and documentation, this is whatever content you've entered in Control Center. On Mashery-generate pages, it's the primary body content. On some pages, this is overridden by a [page-specific label that you can customize](/docs/read/customizing_your_portal/mashery_portal_2_documentation/Labels). {{content.form}} // On pages with forms (sign in, registration, etc.), the form. {{content.secondary}} // Varies by page. On the Documentation pages, it's the navigation sidebar. {{content.logo}} // Your logo, if one is specified. If not, falls back to `{{mashery.area}}`. {{content.navItemsAccount}} // The user account navigation items as a list of linked list elements *without* a parent `
    ` or `
      `. {{content.navItemsMasheryAccount}} // The mashery account navigation items (change your password, email, etc.) as a list of linked list elements *without* a parent `
        ` or `
          `. {{content.navItemsPrimary}} // The primary navigation menu items as a list of linked list elements *without* a parent `
            ` or `
              `. {{content.navItemsSecondary}} // The secondary navigation menu items as a list of linked list elements *without* a parent `
                ` or `
                  `. {{content.navItemsUser}} // The user navigation menu items (sign in, register, logout, etc.) as a list of linked list elements *without* a parent `
                    ` or `
                      `. {{content.masheryMade}} // The Mashery Made logo. If you don't include this, it will be automatically injected into the footer. {{content.terms}} // The account registration Terms of Use. {{content.privacyPolicy}} // A custom privacy policy or terms of use for your organization, if you'd like to include them with the Mashery Terms of Use. {{content.searchForm}} // The search form. {{mashery.title}} // The page title. The H1 content for most pages, or, if unspecified, the Mashery Area name. {{mashery.username}} // The currently logged in user's username. /** * Paths * Placeholder variables for system URLs. */ {{path.apps}} // The My Apps page. {{path.keys}} // The My Keys page. {{path.account}} // The My Account page. {{path.changeEmail}} // The page to change your email. {{path.changePassword}} // The page to change your password. {{path.contact}} // The contact page. {{path.dashboard}} // The Control Center Dashboard. {{path.docs}} // The documentation page. {{path.iodocs}} // The IO Docs page. {{path.logout}} // The logout link. {{path.lostPassword}} // The page to request a lost password. {{path.lostUsername}} // The page to request a lost username. {{path.removeMember}} // The link to trigger a remove account request. {{path.register}} // The page to register a new account. {{path.registerResendConfirmation}} // The page to confirm that a registration email was resent. {{path.removeMembership}} // The page to remove account membership from this Portal. {{path.search}} // The search results page. {{path.signin}} // The sign in page. {{path.viewProfile}} // The current user's profile. ``` In addition to the global placeholders listed above, each template has local placeholder specific to that template or content type. ## The Templates Default values are shown below. ```js // Base layout // The markup structure that all of the content will get loaded into. // {{layout.navUser}} - The wrapper for the user navigation. // {{layout.navPrimary}} - The wrapper for the primary navigation. // {{layout.main}} - The wrapper for the main content area. // {{layout.footer1}} - The wrapper for the first footer content area. // {{layout.navSecondary}} - The wrapper for the secondary navigation. // {{layout.footer2}} - The wrapper for the second footer content area. portalOptions.templates.layout = 'Skip to content' + '{{layout.navUser}}' + '{{layout.navPrimary}}' + '{{layout.main}}' + '
                      ' + '{{layout.footer1}}' + '{{layout.navSecondary}}' + '{{layout.footer2}}' + '
                      '; // My Apps // The page displaying a users registered applications. // {{content.noApps}} - The content to display when the user has no applications. portalOptions.templates.accountApps = function () { var template = '

                      {{content.heading}}

                      '; if (Object.keys(mashery.content.main).length > 0) { mashery.content.main.forEach(function (app) { template += '

                      ' + app.application + '

                      ' + '
                        ' + '
                      • API: ' + (app.api ? app.api : 'None') + '
                      • ' + '
                      • Key: ' + (app.key ? app.key : 'None') + '
                      • ' + '
                      • Created: ' + app.created + '
                      • ' + '
                      ' + '

                      '; if (app.edit) { template += 'Edit This App'; } if (app.delete) { template += 'Delete This App'; } if (app.add) { template += 'Add APIs'; } template += '

                      '; }); } else { template += '{{content.noApps}}'; } if (mashery.content.secondary) { template += '

                      Create a New App

                      '; } return '
                      ' + template + '
                      '; }; // My Account: Email // The page where users can change their Mashery email address. portalOptions.templates.accountEmail = '
                      ' + '

                      {{content.heading}}

                      ' + '' + '' + '{{content.main}}' + '
                      '; // My Account: Email Success // The page confirming email change was successful portalOptions.templates.accountEmailSuccess = '
                      ' + '

                      {{content.heading}}

                      ' + '' + '' + '{{content.main}}' + '
                      '; // My Keys // The page displaying a users API keys. // {{content.noPlanKeys}} - The message to display when a plan has no keys. // {{content.noKeys}} - The message to display when a user has no keys. portalOptions.templates.accountKeys = function () { var template = '

                      {{content.heading}}

                      '; if (Object.keys(mashery.content.main).length > 0 ) { mashery.content.main.forEach(function (plan) { template += '

                      ' + plan.name + '

                      '; if (plan.keys.length > 0) { plan.keys.forEach(function (key) { var secret = key.secret ? '
                    1. Secret: ' + key.secret + '
                    2. ' : ''; template += '

                      ' + key.application + '

                      ' + '
                        ' + '
                      • Key: ' + key.key + '
                      • ' + secret + '
                      • Status: ' + key.status + '
                      • ' + '
                      • Created: ' + key.created + '
                      • ' + '
                      ' + key.limits + '

                      ' + 'View Report' + 'Delete This Key' + '

                      '; }); } else { template += '

                      {{content.noPlanKeys}}

                      '; if (mashery.content.secondary) { template += '

                      Get a Key for ' + plan.name + '

                      '; } } }); } else { template += '{{content.noKeys}}'; if (mashery.content.secondary) { template += '

                      Get API Keys

                      '; } } return '
                      ' + template + '
                      '; }; // My Account // The page where users can manage their Mashery Account details. // {{content.subheading}} - The heading to display above the account details form. portalOptions.templates.accountManage = '
                      ' + '

                      {{content.heading}}

                      ' + '' + '' + '

                      {{content.subheading}}

                      ' + '{{content.main}}' + '
                      '; // My Account: Password // The page where users can change their Mashery password. portalOptions.templates.accountPassword = '
                      ' + '

                      {{content.heading}}

                      ' + '' + '' + '{{content.main}}' + '
                      '; // My Account: Password Success // The page after users have successfully changed their password. portalOptions.templates.accountPasswordSuccess = '
                      ' + '

                      {{content.heading}}

                      ' + '' + '' + '{{content.main}}' + '
                      '; // Add App APIs // Add APIs to an application. // {{content.applicationLabel}} - The label before the application name. // {{content.createdLabel}} - The label before the date the application was created. // {{content.apiLabel}} - The label before the API name. // {{content.keyLabel}} - The label before the API key. // {{content.subheading}} - The heading above the form to add APIs to the application. portalOptions.templates.appAddAPIs = function () { var template = '
                      ' + '

                      {{content.heading}}

                      ' + '
                        ' + '
                      • {{content.applicationLabel}} ' + window.mashery.content.secondary.application + '
                      • ' + '
                      • {{content.createdLabel}} ' + window.mashery.content.secondary.created + '
                      • ' + (window.mashery.content.secondary.api ? '
                      • {{content.apiLabel}} ' + window.mashery.content.secondary.api + '
                      • ' : '') + (window.mashery.content.secondary.key ? '
                      • {{content.keyLabel}} ' + window.mashery.content.secondary.key + '
                      • ' : '') + '
                      ' + '

                      {{content.subheading}}

                      ' + '{{content.main}}' + '
                      '; return template; }; // App Delete // Delete an application // {{content.applicationLabel}} - The label before the application name. // {{content.createdLabel}} - The label before the date the application was created. // {{content.apiLabel}} - The label before the API name. // {{content.keyLabel}} - The label before the API key. // {{content.subheading}} - The heading above the form to delete the application. portalOptions.templates.appDelete = function () { var template = '
                      ' + '

                      {{content.heading}}

                      ' + '
                        ' + '
                      • {{content.applicationLabel}} ' + window.mashery.content.secondary.application + '
                      • ' + '
                      • {{content.createdLabel}} ' + window.mashery.content.secondary.created + '
                      • ' + (window.mashery.content.secondary.api ? '
                      • {{content.apiLabel}} ' + window.mashery.content.secondary.api + '
                      • ' : '') + (window.mashery.content.secondary.key ? '
                      • {{content.keyLabel}} ' + window.mashery.content.secondary.key + '
                      • ' : '') + '
                      ' + '

                      {{content.subheading}}

                      ' + '{{content.main}}' + '{{content.form}}' + '
                      '; return template; }; // Add App APIs: Success // New API keys added to an app. portalOptions.templates.appAddAPIsSuccess = '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '
                      '; // Edit Application // Layout with form to edit an application. portalOptions.templates.appEdit = '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '{{content.form}}' + '
                      '; // App Registration // The app registration page. portalOptions.templates.appRegister = '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '{{content.form}}' + '
                      '; // App Registration Success // The message that's displayed after an application is successfully registered. portalOptions.templates.appRegisterSuccess = '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '
                      '; // Blog: All Posts // The page where all blog posts are listed. portalOptions.templates.blogAll = function () { var template = '

                      {{content.blogTitle}}

                      '; var excerpt = document.createElement('div'); window.mashery.content.main.forEach(function (post) { excerpt.innerHTML = m$.convertMarkdown(post.content); template += '

                      ' + '' + post.title + '' + '

                      ' + '

                      ' + 'By ' + post.author + ' on ' + '

                      ' + '
                      ' + excerpt.textContent.slice(0, parseInt(settings.excerptLength, 10)) + '...' + '

                      ' + settings.labels.blogAll.readMore + '' + post.title + '

                      ' + '
                      '; }); if (window.mashery.content.secondary.pagination) { template += window.mashery.content.secondary.pagination; } return '
                      ' + template + '
                      '; }; // Blog: Single Post // The layout for individual blog posts. portalOptions.templates.blogSingle = function () { var template = '

                      ' + window.mashery.content.main.title + '

                      ' + '

                      ' + 'By ' + window.mashery.content.main.author + ' on ' + '

                      ' + '
                      ' + m$.convertMarkdown(window.mashery.content.main.content) + '
                      '; if (window.mashery.content.main.edit) { template += '

                      Edit Post

                      '; } return '
                      ' + template + '
                      '; }; // Contact // The contact page. portalOptions.templates.contact = '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '{{content.form}}' + '
                      '; // Contact Success // The message displayed after a contact form is successfully submitted. portalOptions.templates.contactSuccess = '
                      ' + '

                      {{content.heading}}

                      ' + '

                      {{content.main}}

                      ' + '
                      '; // Documentation // The layout for API documentation. This page includes an automatically generated navigation menu. // {{content.subheading}} - The heading above the documentation sub-navigation. portalOptions.templates.docs = '
                      ' + '
                      ' + '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '
                      ' + '
                      ' + '

                      {{content.subheading}}

                      ' + '
                        {{content.secondary}}
                      ' + '
                      ' + '
                      ' + '
                      '; // Footer 1 // The first of two footer content sections. portalOptions.templates.footer1 = ''; // Footer 2 // The second of two footer content sections. portalOptions.templates.footer2 = ''; // Forum: All Topics // The main forum page where all topics are listed. // @todo Create this layout forumAll = '

                      The forum content needs to get created.

                      ', --> // 404 // The layout for 404 pages. // portalOptions.templates.fourOhFour = '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '
                      '; // IO Docs // The IO Docs page. // portalOptions.templates.ioDocs = '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '{{content.form}}' + '
                      '; // Join // The layout for existing Mashery users signing into an area for the first time. Mashery Terms of Use *must* be displayed on this page, and will be automatically injected if you omit them. portalOptions.templates.join = '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '{{content.form}}' + '{{content.terms}}' + '
                      '; // Join: Success // The page confirming that an existing Mashery user has joined a new area. portalOptions.templates.joinSuccess = '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '
                      '; // Key Activity // Layout for the key activity report page. // {{content.applicationLabel}} - The label before the application name. // {{content.keyLabel}} - The label before the API key. // {{content.secretLabel}} - The label before the key secret. // {{content.statusLabel}} - The label before the key status. // {{content.createdLabel}} - The label before the date the application was created. // {{content.limits}} - A table displaying any call limits for the key. portalOptions.templates.keyActivity = function () { var template = '

                      {{content.heading}}

                      ' + '' + '

                      {{content.subheadingAPI}}

                      ' + '
                        ' + '
                      • {{content.applicationLabel}} ' + window.mashery.content.secondary.application + '
                      • ' + '
                      • {{content.keyLabel}} ' + window.mashery.content.secondary.key + '
                      • ' + (window.mashery.content.secondary.secret ? '
                      • {{content.secretLabel}} ' + window.mashery.content.secondary.secret + '
                      • ' : '') + '
                      • {{content.statusLabel}} ' + window.mashery.content.secondary.status + '
                      • ' + '
                      • {{content.createdLabel}} ' + window.mashery.content.secondary.created + '
                      • ' + '
                      ' + '{{content.limits}}' + '{{content.main}}'; return '
                      ' + template + '
                      '; }; // Key: Delete // Layout for the delete key page. // {{content.applicationLabel}} - The label before the application name. // {{content.keyLabel}} - The label before the API key. // {{content.secretLabel}} - The label before the key secret. // {{content.statusLabel}} - The label before the key status. // {{content.createdLabel}} - The label before the date the application was created. // {{content.subheadingConfirm}} - The heading above the form where users confirm that they want to delete their key. portalOptions.templates.keyDelete = function () { var template = '

                      {{content.heading}}

                      ' + '

                      {{content.subheadingAPI}}

                      ' + '
                        ' + '
                      • {{content.applicationLabel}} ' + window.mashery.content.secondary.application + '
                      • ' + '
                      • {{content.keyLabel}} ' + window.mashery.content.secondary.key + '
                      • ' + (window.mashery.content.secondary.secret ? '
                      • {{content.secretLabel}} ' + window.mashery.content.secondary.secret + '
                      • ' : '') + '
                      • {{content.statusLabel}} ' + window.mashery.content.secondary.status + '
                      • ' + '
                      • {{content.createdLabel}} ' + window.mashery.content.secondary.created + '
                      • ' + '
                      ' + '

                      {{content.subheadingConfirm}}

                      ' + '{{content.main}}' + '{{content.form}}'; return '
                      ' + template + '
                      '; }; // Logout: Success // The page shown after a user logs out. portalOptions.templates.logout = '
                      ' + '

                      {{content.heading}}

                      ' + '

                      {{content.main}}

                      ' + '
                      '; // Logout: Failed // The page shown when a logout was unsuccessful. portalOptions.templates.logoutFail = '
                      ' + '

                      {{content.heading}}

                      ' + '

                      {{content.main}}

                      ' + '
                      '; // Lost Password Request // The page where users can request their password be reset. portalOptions.templates.lostPassword = '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '{{content.form}}' + '
                      '; // Lost Password Reset // The page shown after a password reset email is sent to the user. portalOptions.templates.lostPasswordReset = '
                      ' + '

                      {{content.heading}}

                      ' + '

                      {{content.main}}

                      ' + '
                      '; // Lost Username Request // The page where users can request their username be reset. portalOptions.templates.lostUsername = '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '{{content.form}}' + '
                      '; // Lost Username Reset // The page where users can reset their username. portalOptions.templates.lostUsernameReset = '
                      ' + '

                      {{content.heading}}

                      ' + '

                      {{content.main}}

                      ' + '
                      '; // Remove Membership // The page where users can remove their membership from this Portal. // {{content.confirm}} - The button text to confirm you want to remove your membership from this Portal. // {{content.cancel}} - The button text to cancel removing your account. portalOptions.templates.memberRemove = '
                      ' + '

                      {{content.heading}}

                      ' + '

                      {{content.main}}

                      ' + '

                      ' + '{{content.confirm}}' + '{{content.cancel}}' + '

                      ' + '
                      '; // Remove Membership Success // The page shown when user membership was successfully removed. portalOptions.templates.memberRemoveSuccess = '
                      ' + '

                      {{content.heading}}

                      ' + '

                      {{content.main}}

                      ' + '
                      '; // No Access // Layout for when the user does not have permission to view the page portalOptions.templates.noAccess = '
                      ' + '

                      {{content.heading}}

                      ' + '

                      {{content.main}}

                      ' + '
                      '; // Custom Pages // The layout for custom pages. portalOptions.templates.page = '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '
                      '; // User Profiles // The layout for user profile pages. // {{content.headingUserInfo}} - The heading above the user's info. // {{content.userWebsite}} - The label before the user's website URL. // {{content.userBlog}} - The label before the user's blog URL. // {{content.userRegistered}} - The label before the date the user registered. // {{content.headingActivity}} - The heading above the user's list of activity. portalOptions.templates.profile = function () { var template = '

                      {{content.heading}}

                      '; if (window.mashery.content.main.admin) { template += '

                      View administrative profile for ' + window.mashery.content.main.name + '

                      '; } template += '

                      {{content.headingUserInfo}}

                      ' + ''; if (window.mashery.content.main.activity) { template += '

                      {{content.headingActivity}}

                      ' + window.mashery.content.main.activity; } return '
                      ' + template + '
                      '; }; // Primary Navigation // The primary navigation content for the Portal. // {{content.menuToggle}} - The label on the button to expand and collapse the navigation menu on smaller screens. portalOptions.templates.primaryNav = ''; // Registration // The registration page. Terms of Use *must* be included on this page, and will be automatically injected if you omit them. // {{content.about}} - The "No Spam" message on the registration page. portalOptions.templates.register = '
                      ' + '
                      ' + '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '{{content.form}}' + '{{content.terms}}' + '
                      ' + '
                      ' + '{{content.about}}' + '
                      ' + '
                      ' + '
                      '; // Registration Email Sent // The page confirming that the users registration email was sent. portalOptions.templates.registerSent = '
                      ' + '

                      {{content.heading}}

                      ' + '

                      We have sent a confirmation email to you at {{content.main}}.

                      ' + '

                      Please click on the link in that e-mail to confirm your account. If you do not receive an email within the next hour, click here to resend confirmation email.

                      ' + '
                      '; // Registration Email Resend // The page requesting the registration email be resent. portalOptions.templates.registerResend = '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '{{content.form}}' + '
                      '; // Registration Email Resent // The page confirming that the registration email was resent. portalOptions.templates.registerResendSuccess = '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '
                      '; // Search // The layout for search results. // {{content.headingNew}} - The heading to display if no search query is provided. // {{content.meta}} - Meta details about the search. // {{content.pagePrevious}} - The text for the link to go to the previous page of results. // {{content.pageDivider}} - The divider between the previous and next page links. // {{content.pageNext}} - The text for the link to go to the next page of results. // {{content.noResults}} - The message to display if no search results are found. portalOptions.templates.search = function () { var template = ''; if (window.mashery.content.newSearch) { template += '

                      {{content.headingNew}}

                      ' + '{{content.searchForm}}'; } else if (window.mashery.content.main) { template += '

                      {{content.heading}}

                      ' + '{{content.searchForm}}' + '

                      {{content.meta}}

                      '; window.mashery.content.main.forEach(function (result) { template += '
                      ' + '

                      ' + result.title + '

                      ' + '

                      ' + result.summary + '
                      ' + '' + result.url + '' + '

                      ' + '
                      '; }); template += '
                      '; if (window.mashery.content.secondary.pagePrevious) { template += '{{content.pagePrevious}}'; } if (window.mashery.content.secondary.pagePrevious && window.mashery.content.secondary.pageNext) { template += '{{content.pageDivider}}'; } if (window.mashery.content.secondary.pageNext) { template += '{{content.pageNext}}'; } template += '
                      '; } else { template += '

                      {{content.heading}}

                      ' + '{{content.searchForm}}' + '{{content.noResults}}'; } return '
                      ' + template + '
                      '; }; // Secondary Navigation // The secondary navigation for the Portal, often included in the footer. portalOptions.templates.secondaryNav = ''; // Secret Visibility // Show key secrets for 30 days. portalOptions.templates.showSecret = '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '
                      '; // Secret Visibility: Success // Key secrets will be shown. portalOptions.templates.showSecretSuccess = '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '
                      '; // Secret Visibility: Error // Key secrets already shown. portalOptions.templates.showSecretError = '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '
                      '; // Sign In // The sign in page. portalOptions.templates.signin = '
                      ' + '
                      ' + '
                      ' + '

                      {{content.heading}}

                      ' + '{{content.main}}' + '{{content.form}}' + '
                      ' + '
                      ' + '{{content.about}}' + '
                      ' + '
                      ' + '
                      '; // User Navigation // The navigation menu for sign in, registration, account, and logout links. portalOptions.templates.userNav = ''; ```

Docs Navigation