What do you need help with?

We are here and ready to help.

Display file library within a public article

How to Display the Internal File Library on Public-Facing Articles

Overview

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:

  1. Injecting the Data: Pulling the file and folder structure from the backend into the article page.
  2. Building the Display: Using JavaScript to dynamically construct a collapsible folder and file list.
  3. Styling the Interface: Applying CSS to make the file tree look clean, professional, and interactive.

Prerequisites: You will need administrative access to the Self-Service Community settings to modify the theme's code.


Step 1: Update the Community 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.

  1. Navigate to Administration → Self-Service → Community.
  2. Select the specific community you wish to modify from the list.

You will now add code to three different sections of the community theme.

A. Add the Data Generation Script to "Viewing an article"

This script is responsible for loading the file and folder data from the server and making it available on the client-side for processing.

  1. In the left-hand navigation list for your selected community, click on “Viewing an article”.
  2. Scroll to the bottom of the code editor and add the following script block.

<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>

 

HTML
<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>

B. Add the Core Functions to "Javascript (JS)"

This JavaScript code contains the core logic for building the file tree and making it interactive.

  1. In the left-hand navigation list, click on “Javascript (JS)”.
  2. Scroll to the bottom of the section and add the following code.

<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>

 

JavaScript
<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>

C. Add the Styling to "Stylesheet (CSS)"

This CSS provides the visual styling for the file tree, including the folder icons and the expand/collapse animation.

  1. In the left-hand navigation list, click on “Stylesheet (CSS)”.
  2. Scroll to the bottom of the section and add the following CSS rules.

<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>

 

CSS
<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>
}

D. Publish Your Changes

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.


Step 2: Add the File Library to an Article

With the theme updated, you can now add the file library to any article you choose.

  1. Navigate to the article where you want the file library to appear and open it in the editor.
  2. Switch to the Source Code view of the article editor.
  3. Add the following line of HTML where you want the library to be displayed.

<!-- end list -->

 

HTML
<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.

  1. Save or Publish the article.

You can now view the article, and you should see a fully interactive and collapsible list of your file library's contents.

Facebook Share Tweet

Was this article helpfu?

Yes No

Thank you for voting

×
Select company

You are related to multiple companies. Please select the company you wish to login as.