Encompassing nearly 4 months of development, this release includes a significant amount of new functionality, as well as some major changes and improvements to existing functionality.

With a release this size, it is nearly impossible to adequately summarize all of the changes and improvements that were made. If you have any questions, need help, or notice any new issues following this release, please contact support@marketpath.com for assistance.

In summary (yes, this is a summary), this release includes a large number of user interface improvements, a new permissions system, live site GDPR controls and capabilities, personalization tools, a new and improved billing system, improvements to domain management, a large number of new and improved frontend developer tools (liquid markup), and other miscellaneous changes, bug fixes, and improvements.


User Interface

Most of the user interface improvements in this release are relatively small, but affect a significant portion of the management interface. Additionally, there are a large number of new dialogs for managing sites, users, and accounts.

  • Reorganized all of the management dialogs (site settings, account settings, agency settings, domains, users, etc.) with additional capabilities. This encompasses numerous changes (too many to list here) - open your site settings in Marketpath CMS and start clicking around for some examples.
  • In entity lists, if an entity does not have a page, display a "New Page" icon instead of an "Edit Page" icon.
  • Include a properties button in "select" dialogs, in select object form fields, and in select object list form fields. This will make it easier to edit related objects without having to leave the context of what you are currently working on.
  • Some minor tweaks for standardization between similar dialogs (eg: calendar entries, blog posts, folders, menu items, etc...).
  • Added a new "wizard" dialog type which is utilized for site, account, and agency creation and may be utilized for other workflows as well.
  • Optionally, allow administrators to ignore the file replacement warning when replacing multiple files.
  • Improved the user profile dialog.
    • Allow users to edit their email address - with the appropriate warnings, email communications, and account verifications.
    • Allow users to delete their account.
  • Completely removed deprecated Froala and Codemirror editors. All users will now be required to use CKEditor and Ace Editor respectively.
  • Remember the last site you edited in your browser. When you log in to the CMS (or navigate directly) automatically pre-select the last managed site.
  • A couple of minor UI improvements to the page edit interface:
    • When editing a page that is currently checked out, only display one combined confirmation to check out both the page and the entity.
    • If you do not want to overwrite the checkout or do not have permission to edit the page, view it in read-only mode.
    • Display the published status of the current page
  • Display selected grid-view objects differently. When opening an item's properties from the grid-view, select it in order to maintain a visual context of which item's properties you are editing or viewing.
  • Removed "Cancel"/"Close" button from all dialogs. The white "x" in the top-right corner performs the same functionality. The template, code, and page edit interfaces still have a "Close" button, however, which performs the additional functionality of checking the item in before closing the tab.
  • Added "Edit Page" button to page dialogs and to entity dialogs for entities that have pages.
  • Other miscellaneous UI styles, bug fixes, and improvements.



This release comes with a significantly improved permissions system. In order to perform any action in Marketpath CMS, a user must have been granted the appropriate permission on the relevant level. For example: in order for a user to publish a page, they must have the "publish" permission for that site.

There are a variety of permissions that pertain to sites, with some additional permissions at the account level, and even more permissions at the agency level.

Users can be granted permissions at the site, account, or agency level. Additionally, entire agencies can be granted permissions at the site or account level. All-in-all, this amounts to a large number of potential permissions configurations that the system now supports.

In order to maintain integrity between all of the potential configurations, a user will be allowed to perform an action if they have been granted the appropriate permission by any of their relationships. For example: if a user has been added to a site but does not have "develop" permissions for that site, and they have "develop" permissions for an agency which also has "develop" permissions for that site, then the user will be able to perform any actions for the site that require "develop" permissions.

Any site, account, or agency users that already existed prior to this release will have all permissions for any sites, accounts, or agencies that they belonged to. When adding a new user (or agency) to a site, account, or agency, you will be able to specify the desired permissions for that user at the time that they are added.

Furthermore, we have simplified the mechanisms for adding agencies to accounts and sites so that the agency can request permission but may also be invited by the account or site (and any permissions assigned to the agency will be automatically assigned to any users belonging to that agency with the relevant permissions).

Any changes effecting (granting, editing, or removing) permissions will automatically and immediately be applied to all relevant users, regardless of whether they are logged in or not.

One further change to permissions with this release is that while anyone may create an agency, they may not utilize that agency until Marketpath has verified that they appear to be a valid agency. This is to prevent abuse from users who would attempt to impersonate another agency in order to gain access to their clients under false pretense.

Finally (and also significantly), we have updated all of the management interfaces and dialogs to respond to user permissions. This means that users should not generally be shown controls which they do not have permission to use.

For example: if a user does not have write or develop permission, they will still be able to view templates but they will view them in read-only mode and will be unable to save, delete, or publish them.

Another example is that users who do not have permission to manage a site will not be shown the list of users or agencies for that site.


GDPR Capabilities

Given the strict requirements and potentially steep penalties related to recent GDPR legislation, we have added a highly functional permissions system to live sites, which is integrated with our new personalization system and may be extended for additional use.

The permissions system utilizes a cookie to store the permissions that user has allowed or denied. Along with whether the permission is allowed or denied, it also has the capability of storing an additional value (eg: if sessions have been allowed, this will store the session identifier). This has benefits and drawbacks, of course.

Some of the drawbacks are that if a user does not allow cookies on the site, then the system will not remember what they have allowed or denied - and will forget who they are entirely between requests. Additionally, if a user clears their cookies then the system will forget who they are and what they have allowed or denied. Furthermore, if a site has multiple domains, each domain will have its own permissions cookie and personalization information will NOT be remembered between domains - so switching back and forth between domains will result in two different and disconnected sets of personalization information.

Some of the benefits are that the developer can easily grant/deny permission as desired either during a request or in the user's browser using javascript.

To grant or deny permissions during a request, a developer should use the {% set_client_permission %} tag. If they want the system to forget a specific permission (regardless of grant/deny), the developer can use the {% unset_client_permission %} tag.

To grant or deny permissions using javascript, the developer will need to parse the "_mp_permissions" cookie. If there are multiple permissions allowed or denied, they are separated by the '|' character. Each permission is represented as a series of values separated by the '^' character. The first value is the permission name. The second value is '1' if the permission is allowed or '0' if the permission is denied. The third value is the date the permission is set to expire (regardless of if the permission was granted or denied). The final value, which is optional, is the value that is saved along with the permission.

To check permissions during a request, a developer should check the {{ client_permissions }} object.

An example permissions cookie value without any additional permissions might be something like this:

"session^1^9/25/2068 7:56:21 PM^44444444-4444-4444-4444-444444444444"
Read: The user has allowed the "session" permission. Their allowance for sessions will expire in 50 years. The value of the session permission is 44444444-4444-4444-4444-444444444444 (their session identifier).

If the developer were to add an additional permission for third part ads, the cookie value might look like this:

"session^1^9/25/2068 7:56:21 PM^44444444-4444-4444-4444-444444444444|thirdpartyads^0^9/25/2019 7:56:21 PM"
In addition to the previous example, this signifies that the user has denied the "thirdpartyads" permission. Their denial for thirdpartyads will expire in 1 year.

Note that while a developer may modify the permissions cookie using javascript, if they set the cookie to an invalid format the effect could be causing the system to forget all permissions just the same as if they had removed the session cookie.


In order to assist with allowing/denying sessions by default and with setting the session length, we have added two new site settings.

To allow sessions by default, check the "Create Session by Default" checkbox (checked by default). To only allow sessions if the user or developer explicitly allows them, uncheck the "Create Session by Default" checkbox.

To change the duration of a session, simply set the "Session Length in Minutes" site property to your desired duration (60 minutes by default). Note that the session length is the amount of time between requests that is required to reset to a new session - not the length of time from the first session request (so if the session length is 60 minutes and user loads a page every 59 minutes, their session would last indefinitely).


Finally regarding permissions, the "session" permission determines the usefulness of the "client" and "session" objects. This means that if a user has denied session permission, the developer will not be able to use the new personalization capabilities of Marketpath CMS.



We have added a number of new personalization capabilities to Marketpath CMS in this release - all of which are controlled by the client permissions (as discussed above under GDPR Capabilities). If a user has not granted permission for a session (via template code, javascript, or the site default), then the only "personalization mechanism" that will work is cookies, and the system will not remember any client or session information between page loads.


This release includes several new ways for the developer to query, update, and remove cookies: {{ cookies }}, {% set_cookie %}, and {% unset_cookie %}.

Note that, while is is technically possible to use cookies for personalization even without user permission, it is not advisable to do so in most circumstances for three reasons:

  1. There is much more overhead related to cookies than there is to other methods of communication.
  2. Cookies may be added, removed, modified, and copied using client-side scripts.
  3. The personalization system was created for a reason and bypassing it could lead to unanticipated legal, technical, or other problems.

There are valid uses for cookies, however. Some of those reasons are:

  1. Saving information that is queryable and updatable using both template code and client-side javascript.
  2. Saving or accessing information between sites or domains that share a base domain name.
  3. Saving information for an extended period of time (longer than the session permission) or in order to make it accessible before/during/after a migration to or from another system.


In Marketpath CMS, the "client" object represents all of the interactions in a browser on a specific computer. Note that this may be conceptually identicial to a user or it may encompass multiple users sharing a browser (as in the case of a public or a shared computer).

Data may be saved to and retrieved from the client, which lasts for as long as the session permission is allowed. This means that if the session permission expires or is denied, the system will forget all data associated with the client.

To save data to the client use {% set_client %}. To query data saved on the client use the {{ client }} object. To remove data from the client use {% unset_client %}.

Note that saving data to the client is different than saving data to the session in that the data will even be remembered between sessions - for as long as the session permission lasts.

For performance and other reasons, you may only save a limited amount of information on the client. The number of properties that can be saved to the client may vary by site, and can be queried using {{ client.max_properties }}. If more properties are added than are allowed, then the oldest properties will be unset.

Additionally, there are other useful properties that are accessible on the client - including the date of the first request, the number of pages viewed, the number of sessions that this client has created, and more.


In Marketpath CMS, the "session" object represents all of the client interactions within a limited amount of time. By default the session length is 60 minutes but the session length may be customized for a site in the site settings. Note that the session length is the amount of time between interactions before a new session is created - not the amount of time from the first interaction (so if the session length is 60 minutes and the user requests a new page every 59 minutes then their session will last indefinitely).

Although not strictly true it is generally assumed that, while a client may encompass multiple users, each session is only related to a single user. This is one of the key differences between the session and the client.

Data saved to and retrieved from the session will only last as long as the session remains active. To save data to the session use {% set_session %}. To query data saved on the session use the {{ session }} object. To remove data from the session use {% unset_session %}.

One other difference between the session and the client is that while the client can only save a limited number of properties, the session is not limited in the number of properties that may be saved to it (although we do not guarantee optimal performance if you start adding thousands of properties to sessions).

The session object also has some useful properties that the developer may utilize - including the session start time, the session end time (if the user does not make any further requests before then) the number of pages viewed, the number of unique pages viewed (ignores refreshes or going back to previously-viewed pages), and the number of error pages viewed (eg: 404, 500, etc... errors), and more.

One final useful property that has been added to the session is the session history - the list of pages that the user has viewed during the current session. Using this property, it is possible to (for example) display links to the last 10 pages the user visited. Or to identify whether a user has recently viewed a specific page (a pricing or conversion page, for example) in order to customize content based on that information. One limitation of the history is that it only stores the last 100 request the user has made - if a user has made more than 100 requests then you will only be able to query the 100 most recent requests.


Billing / Invoices

This release includes a large number of new billing-related improvements, including:

  • Free until go-live!
    • OK, so we've always had this. But hey, it's still worth celebrating
  • Immediate site activation on go-live
    • Un-activated sites are visible in the preview environment but not the live environment
    • Activate sites are visible in both the preview and live environments
    • Sites are activated immediately when payment is received.
  • Specify and udpate a site's package from within Marketpath CMS
  • Full implementation of discount and credit systems - applied automatically to invoices.
  • Pay in advance for the package. Bill retroactively for overages from the previous period.
  • Easily edit billing information from within Marketpath CMS
  • Pay for a site from an Agency
  • Change the payer responsible for a site
  • Full invoice history and invoice details from within Marketpath CMS accessible to anyone with the appropriate billing permissions.
    • Invoices are only visible to the account or agency it was billed to - not to site admins
  • Bulk discounts for large invoices (ranging from 5% off invoices over $500 to 20% off invoices over $10000).
  • Automated site deactivation for unpaid sites (if payment fails for two weeks past the due date - payment during the grace period).
  • Advanced billing capability and flexibility built-in accessible only to Marketpath system adminsitrators - call support if you need billing assistance, to dispute an invoice, or to work out alternative payment arrangements.
  • New billing-related email communications
    • Invoice paid (or failed) notifications
    • Invalid credit card notifications
    • Site deactivation warnings and notifications
  • And more...



We made three significant additions to the way domains are handled in Marketpath CMS: development domains, redirected domains, and custom SSL certificates.

Development Domains

Development domains are free domains that we provide to you which utilize a base Marketpath domain (live01.dev.marketpath.site). Development domains are virtually identicial to custom domains in the way that they are used while developing or viewing a site.

Although development domains are not as pretty as custom domains, they are great for temporary use while developing a site - as the name implies. There is no limitation preventing you from using development domains on your live site if desired, but we recommend using custom domains for some of the reasons discussed below:

  1. Development domains are typically far less readable and relevant to the content of your site, and are also typically more difficult to type than a custom domain.
  2. Development domains are not assiciated with an account as custom domains are. This means that:
    1. Development domains cannot be moved from one site to another within an account.
    2. You do not have to verify the domain when adding a development domain to your site.
    3. After removing a development domain from a site, any other site may add the same development domain - regardless of who owns the site. Note that they cannot add the same development domain so long as it is in use on your site.

The typical workflow for using development domains is:

  1. Create a site using a development domain (or add new content to an existing site using a development domain)
  2. Before taking the new content live, add the custom domain that you ultimately want to use. You will have to verify ownership of your custom domain.
  3. When you are ready to take your new content live, perform a domain swap from the development domain to your custom domain.
    1. You will typically redirect the development domain to the custom domain as a part of this step, although you may choose not to if you want to continue using the development domain for development purposes.
  4. If you have not already, go live.
  5. Verify that everything looks and works as anticipated on the live site.

Redirected Domains

Redirected domains are simply domains that act as aliases of other domains. Any request to a redirected domain will automatically be redirected to the target domain. This makes it easy to (for example) redirect a non-www domain to its www equivalent - or vice versa.

In order to create a redirected domain, both the redirected domain and the target domain must be on the same site. Additionally, you cannot redirect the default domain or a domain used by one or more pages to another domain except as part of a domain swap.

There are several advantages to using Marketpath CMS redirected domains over a regex redirect or other methods or redirecting domains:

  • Redirect domains are not displayed as options in the select domain field (eg: when creating or editing a page)
  • Redirected domains do not count towards the number of custom domains you are allowed to have on a site before being billed extra (so you can have as many redirected domains as you want without incurring additional cost).
  • Redirected domains are significantly faster than other built-in methods of redirecting domains for two reasons:
    • The redirect occurs much sooner while processing the request than other redirect methods
    • Redirected domains return a http 301 response which the browser caches, so the next time the user attempts to go to that page you will be saved an entire round-trip request to the web server.

As an added bonus, we even updated our domain swap functionality to allow you to create a redirected domain at the same time as swapping a domain. You can still choose to use the original functionality (creating a regex redirect), or you can choose not to perform any additional redirection if desired. But really, redirected domains are so useful why would you choose not to?

Custom SSL Certificates

Although it was technically possible before to add custom SSL certificates to a site by contacting Marketpath support, we made it much easier for you to do this for yourself with a simple "Upload Custom SSL Certificate" option on the site domain. And if you make a mistake (like uploading the wrong certificate for example) or if the certificate expires, you can easily remove the custom SSL certificate.

In order to upload a custom SSL certificate, you will have to set the Https mode to either "Allow" or "Require" and save the site domain. You will then be presented with an option to "Add Custom SSL Certificate". Clicking on that option will open a new dialog where you can select your .pfx file and provide the password for it (if you do not know what that means you may want to ask a developer for assistance or to do it for you). When you are ready, click on the "Upload" button and you are done.

Before calling it a day, however, you will want to verify that the SSL Certificate is valid and installed correctly. It may take up to 10 minutes for the SSL Certificate to be installed on your website, so grab a cup of coffee and say hello to the rest of your development team and then come back and re-load your site. If your site load properly and displays the correct organization information in the URL bar then you are done! If you are presented with an SSL certificate verification warning, you may have an error in your certificate or you may need to contact Marketpath for assistance (but hopefully not because our certificate installation processes are flawless).


Liquid Improvements

We made numerous additional improvements and additions to our liquid markup capabilities during this release. In addition to the GDPR/permissions system and the personalization capabilities (discussed previously in detail), some additional changes we made are:



  • Content may be published to inactive sites (e.g. prior to going live), but may not be viewed until the site is activated during go-live.
    • Content may be viewed on the preview site before the site has been activated.
    • Similarly, deactivating a site will prevent any live content from being accessible but the preview content will be accessible.
  • Changed the way site settings work behind the scenes for improved efficiency and flexibility.
  • Attempted to implement a fix for image autorotation in the image editor to make it easier to force the image to the desired orientation.
  • Backend changes to improve future consistency, reliability, and maintainability of the management APIs.
  • Set file content disposition
    • Added default content disposition for documents to site settings for use with uploaded documents.
    • Added the framework for a future improvement to allow overwriting the content disposition setting on individual files (documents, images, etc...).
  • Some minor improvements to SSL Certificate generation and installation for stability, performance, and and more reasonable wait times.
  • Begin tracking live page views.
    • This information may be used in the future to show helpful aggregate trends on sites (eg: popularity of entire site or of specific pages, most visited pages, pages with errors, etc...)
  • Updated almost all of the liquid developer documentation
  • Miscellaneous security and performance improvements



  • Fixed a bug with the page URL generation. If there are multiple instances of a disallowed character in the URL (eg: "_"), they will now all be replaced with '-' instead of just the first occurrence.
  • When a user attempts to copy a page, copy the entity as well.
  • Fixed login error message when login fails due to incorrect username or password
  • Fixed a bug with the default display of datastore items if output directly to a live site by the template without further processing.
  • Other miscelaneous bugfixes