Forum Discussion
I suppose it depends on what kind of logging you're hoping to accomplish.
For example, one option is to use the FreeMarker logging utilities if you're wanting some server-side logging to occur.
Alternatively, if you are wanting to have some client-side logging for troubleshooting/debugging purposes in the browser console (i.e. Developer Tools > Console), then you can leverage jQuery to do this.
In our environment, I created a macro called custom.macro.logging.ftl to simplify client-side logging in our customizations, which looks like this:
<#------------------------------------------------ Functions and Macros for Logging and Debugging Created By: Jeff Shurtliff Last Modified By: Jeff Shurtliff Last Modified Date: 2020-11-03 -------------------------------------------------> <#-------------------- Macro: consoleLog --------------------> <#-- This macro prints an entry to the browser JavaScript console (i.e. console.log) --> <#macro consoleLog logEntry=""> <@liaAddScript> ; (function ($) { console.log("${logEntry}"); })(LITHIUM.jQuery); </@liaAddScript> </#macro> <#-------------------- Macro: consoleError --------------------> <#-- This macro prints an error to the browser JavaScript console (i.e. console.error) --> <#macro consoleError logEntry=""> <@liaAddScript> ; (function ($) { console.error("${logEntry}"); })(LITHIUM.jQuery); </@liaAddScript> </#macro> <#-------------------- Macro: consoleDebug --------------------> <#-- This macro prints a debug message to the browser JavaScript console (i.e. console.debug) --> <#macro consoleDebug logEntry=""> <@liaAddScript> ; (function ($) { console.debug("${logEntry}"); })(LITHIUM.jQuery); </@liaAddScript> </#macro> <#-------------------- Macro: consoleInfo --------------------> <#-- This macro prints an info message to the browser JavaScript console (i.e. console.info) --> <#macro consoleInfo logEntry=""> <@liaAddScript> ; (function ($) { console.info("${logEntry}"); })(LITHIUM.jQuery); </@liaAddScript> </#macro> <#-------------------- Macro: consoleWarn --------------------> <#-- This macro prints a warning message to the browser JavaScript console (i.e. console.warn) --> <#macro consoleWarn logEntry=""> <@liaAddScript> ; (function ($) { console.warn("${logEntry}"); })(LITHIUM.jQuery); </@liaAddScript> </#macro>
Then in my other custom components/macros/functions I am able to easily generate log entries by importing the macro file and calling one of the macros above, as demonstrated below.
<#-- Import the macro file --> <#import 'custom.macro.logging' as logging /> <#-- Attempt to get the user ID --> <#attempt> <#assign userId = user.id /> <@logging.consoleDebug "The User ID is ${userId}" /> <#recover> <@logging.consoleError "Encountered an exception while retrieving the User ID" /> </#attempt>
Then while testing in the browser you can monitor the Console tab in Developer Tools and have a better understanding of what might be failing and why.
(I like to include the text "Encountered an exception while..." in error messages within the <#recover> directive because it reminds me that I should check out the Toolbox to see what the verbose FreeMarker error was so I can troubleshoot even further.)
I hope this helps!
- konerusAdept
Thank you for the quick response Jeff. I am looking at server side logging. When we use the utils where are the logs stored and how can I get a copy of it?
konerus Maybe you can share a bit more about what user behaviour you are trying to create a log of. Because Khoros already has a lot of Analytics capturing built-in which you might consider "logging" in a certain way.
I realized I forgot to comment on the other part of your question about getting "the kind of a variable" which I assume you mean the data type of a variable, e.g. string, hash, sequence, etc.
FreeMarker has some quite a few built-ins to check the data type of a variable, which are explained in the official documentation.
However, to avoid having to call a whole bunch of built-ins whenever I want to know the data type of one of my variables, I created the function below which really comes in handy.
<#-------------------- Function: checkDataType --------------------> <#-- This function returns the data type of the object --> <#function checkDataType object simple=false> <#local dataType = "unknown" /> <#attempt> <#if object?is_string> <#local dataType = "string" /> <#elseif object?is_number> <#local dataType = "number" /> <#elseif object?is_boolean> <#local dataType = "boolean" /> <#elseif object?is_sequence> <#local dataType = "sequence" /> <#if simple?? && !simple> <#attempt> <#local subType = checkDataType(object[0]) /> <#if subType?? && subType != "unknown"> <#local dataType = dataType + "+${subType}" /> </#if> <#recover> <@logging.consoleError "Encountered an exception when attempting to determine data subtype for object" /> </#attempt> </#if> <#elseif object?is_hash> <#if simple?? && !simple && object?is_hash_ex> <#local dataType = "extended_hash" /> <#else> <#local dataType = "hash" /> </#if> <#elseif object?is_date_like> <#local dataType = "date_like" /> <#elseif object?is_method> <#local dataType = "method" /> <#elseif object?is_macro> <#local dataType = "macro_function" /> <#-- Correct syntax for checking marcos is checkDataType(macro) instead of checkDataType(<@macro></@macro>) --> <#-- Correct syntax for checking functions is checkDataType(myFunc) instead of checkDataType(myFunc()) --> </#if> <#recover> <@logging.consoleError "Encountered an exception when attempting to determine data type for object" /> </#attempt> <#return dataType /> </#function>
This way I can use the function to quickly identify the data type and take action accordingly, such as in the example below. (I keep the function in a macro file called custom.macro.common.utils.ftl which is why you see it referenced as such below.)
<#-- Import common utilities --> <#import 'custom.macro.common.utils' as commonUtils /> <#assign someVar = 12345 /> <#-- Ensure the variable below is a string --> <#assign dataType = commonUtils.checkDataType(someVar) /> <#if dataType == 'number' || dataType == 'boolean'> <#assign someVar = someVar?c /> </#if> This is my variable: ${someVar}
Hope this helps!
Related Content
- 3 years ago
- 5 years ago
- 13 years ago