Summary
TeamDynamix allows using limited HTML in KB articles, ticket summaries, and HTML modules. However, script tags, id attributes and other commonly-used features of HTML are blocked by default. This article describes some workarounds for using Bootstrap and CSS in TDX, even with the lack of script tags and id attributes.
Details
In the current release of TeamDynamix, one can utilize Bootstrap v3.4 CSS classes when writing content for KB articles, tickets, service requests, and HTML modules. However, some essential tags are blocked by default for security reasons, such as script tags and id attributes. Since Bootstrap scripts are loaded into every page by TDX, one can use little-known features of Bootstrap as workarounds.
Styles
Only administrators can load custom style sheets into the system. All style, rel and link tags are stripped from HTML before rendering to the user. One solution is to convert the needed CSS style sheets (whether external or from style tags) into in-line styles. Tools such as Premailer can take a page or HTML block, compute the styles from CSS, and generate in-line styles.
Example: Using Python and the Premailer package to convert external stylesheets to in-line styles.
Starting out with the following style:
<style>
.mycustomcss {
font-size: 12px;
}
</style>
<span class="mycustomcss">Applied here</span>
Use this python script to convert to in-line style:
"""
Created on Tue Aug 8 15:32:27 2023
@author: mongefrg
Instructions: save the desired webpage to HTML locally,
name it input.html, and run this script to convert
external stylesheets to in-line styles.
"""
from premailer import Premailer
with open('input.html') as file:
html_content = file.read()
p = Premailer(html_content)
p.disable_basic_attributes = False
p.remove_classes = False
p.remove_unset_properties = True
processed_html = p.transform()
with open('output.html', 'w') as file:
file.write(processed_html)

Resulting in-line style:
<span style="font-size: 12px">Applied here</span>

Some limitations apply. All @media queries, transitions, viewports and animations are still stripped out by TDX. Moreover, in-line styles do not support transitions and animations.
ID Attribute
The ID attribute is normally needed to apply Bootstrap classes. A solution is to apply a custom ID as a class on the target object, and use a class selector in the calling attribute instead of the ID.
Example: adding tabbed content to a KB article
The Bootstrap 3.4 documentation provides an example for creating tabbed content, by using the data-target="targetelementid" attribute in the tab. The target element (tab content) would use the id="targetelementid" attribute, but this gets stripped by TDX. Instead, use data-target=".classSelectorForTargetElement" in the tab, and class="classSelectorForTargetElement" in the tab content element.

The following code would not work in TDX as it uses the ID attribute:
<ul class="nav nav-tabs nav-tabs-inverse">
<li class="active"><a data-toggle="tab" data-target="menu1">Menu 1</a></li>
</ul>
<div class="tab-content">
<div id="menu1" class="tab-pane fade in active">
<h3>Menu 1</h3>
<p>Some content.</p>
<p>You can add images and apply any formatting here.</p>
</div>
</div>
This revised code would work in TDX as it uses class selectors instead of the ID attribute:
<ul class="nav nav-tabs nav-tabs-inverse">
<li class="active"><a data-toggle="tab" data-target=".menu1">Menu 1</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane menu1 fade in active">
<h3>Menu 1</h3>
<p>Some content.</p>
<p>You can add images and apply any formatting here.</p>
</div>
</div>
Resulting tabbed content inside a TDX knowledge base article (saved as a Template to make it re-usable):


Code Examples and Ready-to-Use Templates
To see examples of how this knowledge base has been customized with custom HTML, CSS and Bootstrap components, see our open source code at:
https://github.com/DepressionCenter/EFDC-TDX-KB

Notes
- Note that using Bootstrap for content in TDX is itself a workaround. This is because one is taking advantage of the interface loading Bootstrap classes and scripts without loading them directly. As a result, any custom HTML could potentially break if TDX upgrades its Bootstrap components to an incompatible version, or if it ever removes Bootstrap altogether.
Resources
About the Author
 |
Gabriel Mongefranco is a Mobile Data Architect at the University of Michigan Eisenberg Family Depression Center. Gabriel has over a decade of experience in data analytics, dashboard design, automation, back end software development, database design, middleware and API architecture, and technical writing.
| |
|