ContributionsMost RecentMost LikesSolutionsRe: Community Plugin SDK Compatibility Late to the party here, but I've created a Docker image and published on Docker Hub -- everything you need to get started with the SDK, I think. Re: Community plugin SDK in Docker That was definitely one of the gotchas cgrinton. The other was the confusing error about being unable to create some install directories. (I saw another member struggled with this issue.) I solved that by creating a different location to install the nodejs apps with npm, and setting the environment variable to redirect before running the install for gulp and lithium-sdk. # set a location to install these node apps RUN mkdir /home/sdkuser/.npm-global ENV NPM_CONFIG_PREFIX=/home/sdkuser/.npm-global It would be nice if Khoros support or services decided to create an "official" Docker image for SDK users that they could keep current as the SDK gets versioned (which is infrequent, I know). Happy to donate my Dockerfile to the cause as a start. Community plugin SDK in Docker Hi All, Like others in the Developer forum here, I use the plugin SDK and sometimes struggle to set up the development environment. My main machine is Windows and that's not officially supported for the SDK. For a long time I've used a Linux VM hosted at my company, but as we're working from home that tends to be slower to access now, especially with all of the "source files" on a network folder. I've finally taken the time to create a Docker image that makes setup a breeze. I've used Docker before but this is my first time creating a "recipe" -- it took a lot of trial and error to avoid some of the setup gotchas. The image is here for your docker pull if you want to try it: https://hub.docker.com/repository/docker/cjdinger/khoros-sdk I also shared the original Dockerfile on GitHub because...well...it's my first one of these and who knows what I screwed up. If you know better, you might have a shot at fixing it. I use VS Code on my local host machine to maintain the source files. I also use git (we use GitLab) for source control from within Windows (PowerShell). I use this new Docker container only when I need to run the li commands to build and submit the plugin to our stage environment. Re: Events (occasion) RSS feed for syndication It's why I shared it Natkinson ! And if you find some magic changes that make this better for a GCal feed, please let me know. It's not something I looked into. Was thinking I could expand to at least include a link in each item to the ICS download...but I have not looked at what that would take. Events (occasion) RSS feed for syndication We're using the Events module more, but one thing we were missing was a way to syndicate the events to other sites in a useful way: chronological by date of upcoming event, including title, desc, feature image...etc. I created an endpoint component to produce the RSS feed that I think we need for this. I've decided to share it here in case others find it useful. A few values are coded for our community but most are easily replaced for your case. In the comments I included some sample URLs that control which labels are included in the feed, how many items ahead, etc. If you'd like to see an example of this output, here's a sample feed from our community. <?xml version="1.0" encoding="UTF-8"?> <#-- sample URLs: Default event board: https://communities.sas.com/plugins/custom/sasinstitute/sasinstitute/events-rss Specific event board: https://communities.sas.com/plugins/custom/sasinstitute/sasinstitute/events-rss?board=community-events Specific event board, no event message body in feed: https://communities.sas.com/plugins/custom/sasinstitute/sasinstitute/events-rss?board=community-events&description=false Next 10 events: https://communities.sas.com/plugins/custom/sasinstitute/sasinstitute/events-rss?board=community-events&size=10 Next 5 events for "Users Groups": https://communities.sas.com/plugins/custom/sasinstitute/sasinstitute/events-rss?board=community-events&label=Users%20Groups --> <#-- our community domain, checking for stage vs prod --> <#assign root="https://communities.sas.com"/> <#if config.getString("phase", "prod") == "stage"> <#assign root = "https://communities-lithiumstage.sas.com" /> </#if> <#assign board = http.request.parameters.name.get("board","events")/> <#assign label = http.request.parameters.name.get("label", "")/> <#assign filter = http.request.parameters.name.get("filter","upcoming")/> <#assign include_desc = http.request.parameters.name.get("description", "true")/> <#assign size= http.request.parameters.name.get("size","5")/> <#assign time_filter = ""/> <#if filter != ""> <#assign time_filter = "AND occasion_data.status = '${filter}'"/> </#if> <#assign label_filter = ""/> <#if (label)?has_content> <#assign label_filter = "AND labels.text MATCHES('${label}')"/> </#if> <#assign board_href = "#"/> <#assign board_title = "Events"/> <#assign board_description = ""/> <#assign boardq = rest("2.0", "/search?q=" + "select title, description, view_href from boards where id='${board}' and conversation_style='occasion'"?url)/> <#if boardq.data?? && boardq.data.items?? && boardq.data.items?size gt 0> <#assign board_href = "${boardq.data.items[0].view_href}"/> <#assign board_title = "${boardq.data.items[0].title}"/> <#assign board_description = "${boardq.data.items[0].description}"/> <#if board_description==""><#assign board_description = "${board_title}"/></#if> </#if> <#assign events = rest("2.0", "/search?q=" + "select subject, view_href, body, videos, images, occasion_data.start_time, labels from messages where board.id='${board}' ${time_filter} ${label_filter} AND depth=0 order by occasion_data.start_time ASC LIMIT ${size}"?url )/> <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" > <channel> <title>${board_title}</title> <link>${root}${board_href}</link> <atom:link href="${http.request.url?replace('&','&')}" rel="self" type="application/rss+xml"/> <description>${board_description}</description> <#if events.data?? && events.data.items??> <#list events.data.items as event > <item> <title>${event.subject} | ${event.occasion_data.start_time?datetime?string("dd-MMM-yyyy")}</title> <link>${root}${event.view_href}</link> <guid>${root}${event.view_href}</guid> <#if include_desc == "true"> <description>${event.body?html}</description> </#if> <#-- add either an image from the message or a video thumb, whichever we have --> <#if event.images?? && event.images.query??> <#assign images = rest("2.0", "/search?q=" + "${event.images.query}"?url )/> <#list images.data.items as image> <#-- need to escape & in the XML, and these URLs can sometimes have them --> <enclosure url="${root}${image.medium_href?replace('&','&')}" length="0" type="image/jpeg"/> <#break> </#list> <#elseif event.videos?? && event.videos.query??> <#assign videos = rest("2.0", "/search?q=" + "${event.videos.query}"?url )/> <#list videos.data.items as video> <enclosure url="${video.thumb_href?replace('&','&')}" length="0" type="application/x-shockwave-flash"/> <dc:type>MovingImage</dc:type> <#break> </#list> </#if> <#if event.labels?? && event.labels.query??> <#assign labels = rest("2.0", "/search?q=" + "${event.labels.query}"?url )/> <#list labels.data.items as label> <#-- category tag: good enough for WordPress, so good enough for us --> <category><![CDATA[${label.text?html}]]></category> </#list> </#if> <#-- this "pubDate" will always be in the future which may confuse some aggregators --> <#-- but I didn't know how else to encode the event date/time in the feed --> <pubDate>${event.occasion_data.start_time?datetime?string["EEE, dd MMM yyyy HH:mm:ss"]} GMT</pubDate> </item> </#list> </#if> </channel> </rss> I've tried the feed in some aggregators like Feedly and in Microsoft Outlook -- it seems to pass muster. Questions and suggestions are welcome! Re: Component to preview attachments in lightbox Thanks Claudius for the reply. From what I see the lightbox previewer leverages a service from box.com to preview the content of known types like PDF, CSV, etc. I'm not going to replicate that! I'm guessing there must be a built-in wrapper for this in the community platform...but perhaps it's not a component that we can include in our own custom components. Component to preview attachments in lightbox We customized our TKB Article Page quilt and placed attachments near the top. We fetch the details using the APIs. Looks like this: (See it in action here if you like.) The action when you click on the attachment will download in your browser, but I'm interested in offering a lightbox preview the same as the default attachment component. Is there a component I can use to wrap this feature in? Re: Khoros Communities 21.1 Release Notes Re: moving the Not Spam button NickQuinn -- we ended up doing that on our site by adding a little script, called on the last_chance_html.ftl: <script> ;(function ($) { function moveNotSpamButton() { var btn = document.getElementById('lia-notSpamButton'); var after = document.getElementById('searchBreadCrumb'); after.append(btn); } if (window.location.href.indexOf("/spam/searchpage") != -1) moveNotSpamButton(); }) (LITHIUM.jQuery); </script> We'll see if the updates to the page affect this or whether we need to adjust. Re: How We Built It: Access Signposting AndyK Tell me about this "settings list editor" -- is that a feature I have not discovered in Admin? Like a property key-value thing? Re: Private/Visibility logo overlay in Atlas I swear I searched...but never would have come up with the "signposting" term. Still, it fits. Thanks!