ContributionsMost RecentMost LikesSolutionsRe: Can We Truncate Subscription Email Post Body? Hi Keith, as you discovered, the "?truncate" syntax is for Apache FreeMarker, while email templates utilize Apache Velocity 1.5. In the Marketo community thread, they referred to a couple of variables: $String: They were using this to refer to a StringUtils object. $display: They were using this to refer to a DisplayTool object (from Velocity Tools) Using utilities/tools like these would require that they have been placed on the context by the environment (the community application). Unfortunately Khoros does not provide access to these or other utilities. So you would need to find a way to do this yourself using conditional logic and the methods provided on the String itself. Here is the source code for those two utilities, which you could try to emulate: chop from StringUtils @ Velocity 1.5 truncate from DisplayTool @ Velocity Tools 3.2 Broadly, any implementation would need to use the "length" method (to determine whether to truncate) and then conditionally use the "substring" method, plus some concatenation. Re: How to set predefined-only while creating GroupHub I did a little bit of testing, and I was able to set this setting using API v1 on an individual Idea Exchange within the Group Hub: GET /restapi/vc/boards/id/xxx/settings/name/label.allowed_labels * Returned "freeform-only" POST /restapi/vc/boards/id/xxx/settings/name/label.allowed_labels/set * value=predefined-only GET /restapi/vc/boards/id/xxx/settings/name/label.allowed_labels * Returned "predefined-only" After doing this, I did see the labels being enforced in the "New Idea" flow. I was not able to work with the group hub itself in API v1, and I did not get a chance to try API v2, but I assume that it would work in the same way. Let me know how that goes! Re: How to set predefined-only while creating GroupHub Hi Akash, the key for this setting should be label.allowed_labels — does this prefixed key work when using the API? Re: Different CSS for Unread Topics Cloud_Spanner wrote: The scenario I am trying to solve for is: A power user will want to know if there are unread comments on a topic that they have already viewed. The subject will have the lia-message-unread class if there are any unread messages in the thread. This functionality is related to the image that can denote threads as being "read by moderators" (or not) to indicate where mods might want to spend attention. So it should work by the same rules as that image. I believe in some layouts there is also the ability to show a column of the number of unread messages in a thread. Unfortunately I can't remember the details about how to enable that column, but someone else may know. Re: Happy Holidays - Christmas hats for all users Hoekstra_VFZ wrote: For instance on the GroupHubPage there is some DOM event listener from Khoros that removes all nodes inside the node of the avatar img. So the hats are removed. I had to make a timer to run the function again after the removal event. Does anyone know why Khoros does this?? I see you are using a DOMContentLoaded listener, but for JS like this, try using the liaAddScript macro, which should place your JS at the bottom of the body and also help to ensure it runs after other late page setup work. A performance concern: the MutationObserver on document.body is firing when any element is added to the body without className === "vfz-hat" , which could happen thousands of times on some pages. Each time, it does a fair amount of work and does not detect the hat(s) previously added, so it adds another hat. In my test on a profile page, I saw 70 img.vfz-hat for 10 user icons. These overlapping hats and the work to manage them could cause some performance issues for many users. I suggest to place breakpoints & logging in placeHatOnCLass to ensure it is only being called on those images that do not already have a hat displayed. As community DOM is very complex and varied across pages, and it can also be very dynamic, this is a case where rigid structure assumptions ( parentNode , className instead of classList , indexed access like [0] ) can be brittle, and using the built-in jQuery instance can be a lifesaver. For example, this check will determine if an element or any parent has the vfz-hat class: if ($(element).closest('.vfz-hat').length) For figuring out which images need hats, you can bake the whole search into the initial selector (even without jQuery) : // The current implementation loops over all querySelectorAll(".lia-user-info-group .lia-link-navigation") and then over getElementsByTagName("img") and then looks around for ".vfz-hat" which it can't find because the class is on a sibling of an ancestor. This one-liner finds them all: // jQuery $(".lia-user-info-group .lia-link-navigation img:not(.vfz-hat + * img)") // DOM document.querySelectorAll(".lia-user-info-group .lia-link-navigation img:not(.vfz-hat + * img)") Re: html entity decode Hi Peter, you are correct that FreeMarker did not implement HTML processing like decoding. This was deliberate: FreeMarker's primary use case is to output HTML, so to prevent common security vulnerabilities they designed it so that you work with raw data, and escaping for HTML is the final step before outputting. We're stretching FreeMarker past its design goals, doing much more complex things like API calls and data transformation -- so we did add a utility: utils.html.unescaper.unescape(...). The usual caveats apply: FreeMarker is not a programming language; it is primarily designed for displaying data and is not great at converting or building data. If the message body is being sent somewhere else, it may be a better idea to implement all the HTML post-processing in that environment. This would also make it easier to tweak the algorithm, and it might make user requests faster by offloading some work from the community. Unescaping should only be done on one continuous block of HTML text, with no HTML elements present. That is, all elements must be removed. Even if you strip all HTML, the unescape may result in HTML (because the original escaped text may look like HTML). Once unescaped, make sure it is never accidentally placed directly in an HTML context without proper escaping. Re: dynamic change when changing freemarker variable ? FreeMarker is handled on the server side in order to generate the HTML that will be sent to the user. Once the page has been generated, FreeMarker is no longer relevant. So if you want to do scripted interaction like having a clickable button, that would involve JavaScript rather than FreeMarker. If you want JS that can switch between visible items, then the data for all the items would need to be sent in the HTML, and you could use CSS to hide the inactive items. Any state about which items are visible would be known in JavaScript and manipulated, e.g., by adding and removing classes. Re: API for "Hide messages in this board from lists" Hey Claudius & Tyson, this is a board-level setting called config.hide_messages_from_nodes_in_lists You can grab a list of all the boards that do not have this setting set, build a LiQL "IN" clause with those IDs, and cache that clause. You could use that anywhere you need to filter messages down. This is one of those cases where "NOT IN" syntax would be convenient, but unfortunately as you know it is not supported. Re: png attachment success response but blank data in the attachement Try downloading the raw attachment file and looking at its contents. The file data could be getting corrupted before reaching the server. Note that in the request contents you pasted, there is no actual image data. You could also try to adjust the integration so that it specifically sends the file with an image/png content-type instead of application/octet-stream. Re: Attachment API call content encoding The request itself should be multipart/form-data. The attachment should have some content-type appropriate for the file (but may get rejected, based on community configuration). Specific details here: https://developer.khoros.com/khoroscommunitydevdocs/docs/create-a-message-with-an-attachment