How to Display the Internal File Library on Public-Facing Articles
Your platform's file library is a powerful, internally-facing repository for storing shared documents, images, and other content used across your articles. While its primary function is for internal use, you can make this library visible within a public article. This creates a dynamic, navigable file tree that allows users to browse and download files directly from a knowledge base article.
This guide will walk you through the process of adding custom code to your community's theme to enable this functionality. The solution involves three main parts:
Prerequisites: You will need administrative access to the Self-Service Community settings to modify the theme's code.
First, you need to add the necessary scripts and styles to your community's theme. These changes will provide the foundation for displaying the file library wherever you choose.
You will now add code to three different sections of the community theme.
This script is responsible for loading the file and folder data from the server and making it available on the client-side for processing.
<details> <summary><strong>Code Explanation</strong></summary> This code snippet uses your platform's templating language ({% for ... %}) to loop through all the folders and files in your library. For each item, it creates a JavaScript object containing its essential properties (like ID, name, parent folder, and URL) and pushes it into one of two arrays: library_folders or library_files. Finally, it triggers the build_library function to start constructing the visual file tree. </details>
{% for ... %}
library_folders
library_files
build_library
<span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> <span class="hljs-comment">// Build the file repository data structures</span> <span class="hljs-comment">//-----------------------------------------------------</span> <span class="hljs-keyword">var</span> library_folders = []; <span class="hljs-keyword">var</span> library_files = []; <span class="hljs-comment">// Loop through server-side folder data and populate the JS array</span> {%<span class="hljs-keyword">for</span> f <span class="hljs-keyword">in</span> sb.library_files.folders %} library_folders.push({ <span class="hljs-attr">id</span>: <span class="hljs-string">'{{f.id}}'</span>, <span class="hljs-attr">parent_id</span>: <span class="hljs-string">'{{f.parent_id}}'</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'{{f.name}}'</span> }); {% endfor %} <span class="hljs-comment">// Loop through server-side file data and populate the JS array</span> {%<span class="hljs-keyword">for</span> f <span class="hljs-keyword">in</span> sb.library_files.files %} library_files.push({ <span class="hljs-attr">id</span>: <span class="hljs-string">'{{f.id}}'</span>, <span class="hljs-attr">folder_id</span>: <span class="hljs-string">'{{f.folder_id}}'</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'{{f.name}}'</span>, <span class="hljs-attr">url</span>: <span class="hljs-string">'{{f.url}}'</span>, }); {% endfor %} <span class="hljs-comment">// Find the designated container on the page and start building the library</span> build_library($(<span class="hljs-string">'.library'</span>), library_folders, library_files, <span class="hljs-number">0</span>); <span class="hljs-comment">// Bind the click events to make folders collapsible</span> library_folder_bind(); <span class="hljs-comment">//-----------------------------------------------------</span> </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
This JavaScript code contains the core logic for building the file tree and making it interactive.
<details> <summary><strong>Code Explanation</strong></summary> This block defines two key functions: <ul> <li><code>build_library</code>: A recursive function that constructs the HTML for the file tree. It iterates through folders, finds their sub-folders and files, and then calls itself to build out the nested levels, creating the parent-child structure.</li> <li><code>library_folder_bind</code>: This function finds all the folder elements and attaches a "click" event listener to them. When a user clicks a folder, it toggles the visibility of its contents and rotates the caret icon, creating the expand/collapse effect.</li> </ul> </details>
<span class="hljs-comment">//------------------------------------</span> <span class="hljs-comment">// Dynamically builds the nested list for the file library</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">build_library</span>(<span class="hljs-params">$list, folders, files, folder_parent_id</span>) </span>{ <span class="hljs-keyword">if</span> (folders.length) { <span class="hljs-comment">// Get the direct child folders for the current parent ID</span> <span class="hljs-keyword">var</span> folder_children = folders.where(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">i</span>) </span>{ <span class="hljs-keyword">return</span> i.parent_id == folder_parent_id }); <span class="hljs-comment">// Loop through the child folders</span> $.each(folder_children, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">i, folder</span>) </span>{ <span class="hljs-comment">// Build the list of files within this folder</span> <span class="hljs-comment">//--------------------------------</span> <span class="hljs-keyword">var</span> file_html = <span class="hljs-string">''</span>; <span class="hljs-keyword">var</span> file_items = files.where(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">ii</span>) </span>{ <span class="hljs-keyword">return</span> ii.folder_id === folder.id }); $.each(file_items, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">i, f</span>) </span>{ file_html += (<span class="hljs-string">'<li><a href="'</span> + f.url + <span class="hljs-string">'">'</span> + f.name + <span class="hljs-string">'</a></li>'</span>); }); <span class="hljs-comment">//--------------------------------</span> <span class="hljs-comment">// Create the folder item, including its files</span> <span class="hljs-keyword">var</span> $folder_item = $(<span class="hljs-string">'<li><span class="folder_caret">'</span> + folder.name + <span class="hljs-string">'</span><ul class="folder_nested">'</span> + file_html + <span class="hljs-string">'</ul></li>'</span>); <span class="hljs-comment">// Recursively build the sub-folders for the current folder</span> <span class="hljs-comment">//--------------------------------</span> <span class="hljs-keyword">var</span> $subList = $folder_item.find(<span class="hljs-string">'.folder_nested'</span>); build_library($subList, folders, files, folder.id); $list.prepend($folder_item); <span class="hljs-comment">//--------------------------------</span> }); } <span class="hljs-comment">// Build the files that exist in the root folder (no parent)</span> <span class="hljs-comment">//--------------------------------</span> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">parseInt</span>(folder_parent_id) === <span class="hljs-number">0</span>) { <span class="hljs-keyword">var</span> $file; <span class="hljs-keyword">var</span> file_items = files.where(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">ii</span>) </span>{ <span class="hljs-keyword">return</span> <span class="hljs-built_in">parseInt</span>(ii.folder_id) === <span class="hljs-number">0</span> }); $.each(file_items, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">i, f</span>) </span>{ $file = $(<span class="hljs-string">'<li class="first"><a href="'</span> + f.url + <span class="hljs-string">'">'</span> + f.name + <span class="hljs-string">'</a></li>'</span>); $list.append($file); }); } <span class="hljs-comment">//--------------------------------</span> <span class="hljs-keyword">return</span>; } <span class="hljs-comment">// Binds the click event to folder items to allow expanding/collapsing</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">library_folder_bind</span>() </span>{ <span class="hljs-keyword">var</span> toggler = <span class="hljs-built_in">document</span>.getElementsByClassName(<span class="hljs-string">"folder_caret"</span>); <span class="hljs-keyword">var</span> i; <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i < toggler.length; i++) { toggler[i].addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>() </span>{ <span class="hljs-comment">// Toggle the 'active' class on the nested list to show/hide it</span> <span class="hljs-built_in">this</span>.parentElement.querySelector(<span class="hljs-string">".folder_nested"</span>).classList.toggle(<span class="hljs-string">"active"</span>); <span class="hljs-comment">// Toggle the 'caret-down' class to rotate the arrow icon</span> <span class="hljs-built_in">this</span>.classList.toggle(<span class="hljs-string">"caret-down"</span>); }); } } <span class="hljs-comment">//------------------------------------</span>
This CSS provides the visual styling for the file tree, including the folder icons and the expand/collapse animation.
<details> <summary><strong>Code Explanation</strong></summary> This CSS code handles all visual aspects. It removes default list bullets, adds padding, and styles the folder caret icon (using the Unicode character \25B6 for an arrow). Crucially, it hides nested lists (.folder_nested) by default and then uses the .active class (toggled by the JavaScript) to display them when a folder is expanded. The .caret-down class handles the rotation of the arrow icon. </details>
caret
\25B6
.folder_nested
.active
.caret-down
<span class="hljs-comment">/* Remove default bullets and reset margin/padding for the main library container */</span> <span class="hljs-selector-tag">ul</span><span class="hljs-selector-class">.library</span> { <span class="hljs-attribute">list-style-type</span>: none; <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>; <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>; } <span class="hljs-selector-tag">ul</span><span class="hljs-selector-class">.library</span> <span class="hljs-selector-tag">li</span> { <span class="hljs-attribute">padding-top</span>: <span class="hljs-number">4px</span>; <span class="hljs-attribute">padding-bottom</span>: <span class="hljs-number">4px</span>; <span class="hljs-attribute">font-size</span>: <span class="hljs-number">15px</span>; } <span class="hljs-comment">/* Add left margin to root-level files to align them with files inside folders */</span> <span class="hljs-selector-tag">ul</span><span class="hljs-selector-class">.library</span> > <span class="hljs-selector-tag">li</span><span class="hljs-selector-class">.first</span> { <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">28px</span>; } <span class="hljs-comment">/* Style the caret/arrow for folders */</span> <span class="hljs-selector-tag">ul</span><span class="hljs-selector-class">.library</span> <span class="hljs-selector-class">.folder_caret</span> { <span class="hljs-attribute">cursor</span>: pointer; user-select: none; <span class="hljs-comment">/* Prevent text selection when clicking */</span> <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">500</span>; <span class="hljs-attribute">font-size</span>: <span class="hljs-number">16px</span>; } <span class="hljs-comment">/* Create the caret/arrow with a unicode character and style it */</span> <span class="hljs-selector-tag">ul</span><span class="hljs-selector-class">.library</span> <span class="hljs-selector-class">.folder_caret</span><span class="hljs-selector-pseudo">::before</span> { <span class="hljs-attribute">content</span>: <span class="hljs-string">"\25B6"</span>; <span class="hljs-comment">/* Right-pointing triangle */</span> <span class="hljs-attribute">color</span>: black; <span class="hljs-attribute">display</span>: inline-block; <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">6px</span>; } <span class="hljs-comment">/* Rotate the caret/arrow icon when clicked (using JavaScript) */</span> <span class="hljs-selector-tag">ul</span><span class="hljs-selector-class">.library</span> <span class="hljs-selector-class">.caret-down</span><span class="hljs-selector-pseudo">::before</span> { <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">rotate</span>(<span class="hljs-number">90deg</span>); } <span class="hljs-comment">/* Hide the nested list by default */</span> <span class="hljs-selector-tag">ul</span><span class="hljs-selector-class">.library</span> <span class="hljs-selector-class">.folder_nested</span> { <span class="hljs-attribute">display</span>: none; } <span class="hljs-comment">/* Show the nested list when the user clicks on the caret/arrow */</span> <span class="hljs-selector-tag">ul</span><span class="hljs-selector-class">.library</span> <span class="hljs-selector-class">.active</span> { <span class="hljs-attribute">display</span>: block; <span class="hljs-attribute">padding-left</span>: <span class="hljs-number">20px</span>; <span class="hljs-comment">/* Indent nested items */</span> }
Once you have added all three code blocks, click the Publish button in the top right corner to save the changes to your community theme.
With the theme updated, you can now add the file library to any article you choose.
<!-- end list -->
<span class="hljs-tag"><<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"library"</span>></span><span class="hljs-tag"></<span class="hljs-name">ul</span>></span>
This empty unordered list acts as a placeholder. The JavaScript you added in Step 1 will find this element (by its class .library) and automatically populate it with the entire file and folder structure.
.library
You can now view the article, and you should see a fully interactive and collapsible list of your file library's contents.
Was this article helpfu?
Thank you for voting
You are related to multiple companies. Please select the company you wish to login as.