Server Side JavaScript
Last Updated: 20 Apr 2018
This entire manual refers to a feature that was added in version 5.4.0.0
Introduction
You can execute Server Side JavaScript (SSJS) in Content Containers and Design Parse Files by including the runat="server"
attribute when using a <script>
tag. For example:
<script runat="server"> print('<h1>%asset_name%</h1>'); </script>
You can also execute JavaScript from a JS File by sourcing it using the src
attribute, for example:
<script runat="server" src="./?a=XXXX"></script>
This functionality is similar to that of the JavaScript Processing field on the REST Resource JS asset.
When used in Content Containers, SSJS is not processed at the time of the processing of the Content Container content. Instead, it is processed at the global level along with any Global Keyword Replacements.
Global Variables
You can set global JS variables which can be accessed by other Content Containers in the page processing.
For example, if I have a nested Standard Page at the top of my Design Parse File code which has the following SSJS code:
<script runat="server"> var userName = '%globals_user_attribute_username%'; </script>
I can then access the same global variable at any other point in the Matrix page generation, either in another Content Container or in the Design Parse File code:
<script runat="server"> print(userName); </script>
Attributes
You can pass additional attributes into the <script>
tag for the server side functionality including:
runat="server"
- Enables the JavaScript code within the tag to run server side.evalkeywords="post"
- By default, keywords are evaluated before the JS is processed. Adding this attribute will make the keywords evaluate after the JS has been processed.This only applies to Global Keywords. In-context asset specific keywords such as %asset_name% will always need to be evaluated in the context of where they are printed.
log="log_prefix"
- Adding this attribute will log any output from the JavaScript as an entry into the Matrix System log. The value of the log attribute will prefix the messages that are printed via the JSprint()
function.
Performance Mode
You can see metrics of the performance of the the Server Side JavaScript within Performance Mode. For example:
Three entries are shown under the Asset the JavaScript block is executed under and includes:
- Process server side JS "pre" keywords - Time take to process keyword replacements before the JS has been processed.
- Process server side JS - Time taken to process the JS code.
- Process server side JS "post" keywords - Time take to process keyword replacements after the JS has been processed.
Disabling SSJS
You are able to disable all JavaScript from running on the server using the runat="server"
method, by adding the following query string parameter to the URL:?SQ_DISABLE_SERVER_JS
The JavaScript in the Content Container will print within the HTML source and execute client side as normal JavaScript. This allows debugging of the JavaScript within the source code of the page.
You need to have Write Access to the Content Container for this query string to take effect.
Viewing SSJS
If you have Write Access to an asset, you can append ?SQ_VIEW_SERVER_JS
to the URL when previewing it on the front-end in order to see a full output of the JS code that was sent to the JS engine in Matrix.
This is useful if you are getting JS errors on the front-end that relate to a specific line number in your code, as you will be able to track down exactly which line the error is referring to.
For example, let's say you got an error similar to the one in the example below. The error points to line 20 in the JS code.
Viewing the front-end page with ?SQ_VIEW_SERVER_JS
appended to the URL, you can see which line the error is referring to. You can also use JS comments to help indicate which specific asset each JavaScript block is coming from.
Processing Order
It's important to understand how Matrix will process Keywords and SSJS and the order of which these get evaluated.
Key rules to remember for Keyword Replacements:
- Asset Keywords always get replaced in context (ie: %asset_name% in Standard Page and Asset Listing Type Format Content Containers and %frontend_asset% keywords).
- Global Keywords get replaced further up but before all SSJS by default.
- Global Keywords in SSJS with
evalkeywords="post"
attribute get replaced after all SSJS.
Matrix also replaces Global Keywords and processes SSJS in two separate places: at the Globals level and in the Design Parse File.
Therefore, the Matrix processing order of these are as follows:
- Content Containers - Asset & Frontend Asset Keywords
- All Global Keywords
- All SSJS
- All Global Keywords in SSJS with
evalkeywords="post"
- Parse File - Global Keywords
- Parse File - SSJS
- Parse File - Global Keywords in SSJS with
evalkeywords="post"
run_ssjs Keyword Modifier
Sometimes you might want to execute SSJS code within the contents of an asset earlier than at the global level. For example, when using the contents of an asset in a Trigger Action.
In order to do this, you can use the ^run_ssjs
Keyword Modifier to execute any SSJS code found within the contents of a keyword as a separate processing thread. For example:
%globals_asset_contents_raw:1234^run_ssjs%
Examples
This section will show you some examples of the various ways you can use SSJS and the different outcomes you will get depending on what keywords you use and how you print the code to the front-end.
Basic Example
This example will conditionally print a <metadata>
SEO based section tag based on the value of the current frontend URL the user is viewing.
<script runat="server"> //Create a variable with the current frontend asset's URL var frontendURL = '%frontend_asset_url%'; //Create a variable for the section string var section = ''; //Set the section string based on the section where the current URL is located under if(frontendURL.indexOf('/manuals') > 0){ section = 'Manuals'; }else if(frontendURL.indexOf('/tutorials') > 0){ section = 'Tutorials'; }else if(frontendURL.indexOf('/news') > 0){ section = 'News'; } //Print a metadata tag for the current section if it is not empty if(section != ''){ print('<meta property="article:section" content="' + section + '"/>'); } </script>
This SSJS code could then be placed somewhere inside the <head>
tag of the page design.
List Assets From a Metadata Related Asset Field
This example takes a list of assets from a Related Asset Metadata Field and loops through each one to print information about each asset in an unordered list, similar to what you might use an Asset Listing for.
<script runat="server">
//Store array of assets from metadata field into a variable
var assets = %asset_metadata_related^json_decode^as_asset:asset_name_linked^empty:[]%;
//Only run if there are actually any assets in the array
if(assets.length > 0){
print('<ul>');
//For each asset, print the value
assets.forEach(function(asset){
print('<li>'+ asset +'</li>');
});
print('</ul>');
}
</script>
The important thing to notice here is that the keyword will be replaced before the JS is processed. So the JS will actually see an array of data that is directly assigned to the assets
variable, rather than a keyword string.