Back to main page Traveling Coderman

Rendering a file structure with Prism in Eleventy

In this post, I show you how I use prism-treeview to render file system structures in an Eleventy blog.

src
|-- index.njk
`-- assets
`-- portrait.png

While keeping the mark up simple.

src/
|-- index.njk
`-- assets/
`-- portrait.png

Prism Treeview 🔗

The Prism plugin prism-treeview extends Prism with a language treeview to display file system structures. The JavaScript file registers the language and defines the logic how to convert the markup into HTML. The Stylesheet file includes the formatting.

_includes
`-- treeview.css
11ty
`-- prism-treeview.js
.eleventy.js

In the Eleventy config .eleventy.js, I load the JavaScript file require("./11ty/prism-treeview.js");. The Eleventy Docs explain how to setup general syntax highlighting.

Reducing the footprint of the CSS 🔗

The stylesheet file treeview.css has a footprint of 17.6 KB. This is due to the icons it directly embeds.

Since I already load Font Awesome icons on every page, I changed the CSS file to use these icons instead. Font Awesome describes how to use icons in pseudo elements.

// ...

.treeview-part .entry-name:before
{
display: inline-block;
font-style: normal;
font-variant: normal;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
font-family: "Font Awesome 5 Free";
color: white;
font-weight: 900;
}

.treeview-part .entry-name[class*="ext-"]:before {
content: "\f15b";
}

.treeview-part .entry-name.dir:before {
content: "\f07b";
}

.treeview-part .entry-name:is(.ext-ts, .ext-js, .ext-njk, .ext-css):before {
content: "\f1c9";
}

.treeview-part .entry-name.ext-js:before {
font-family: "Font Awesome 5 Brands";
content: "\f3b9";
}

.treeview-part .entry-name.ext-css:before {
font-family: "Font Awesome 5 Brands";
content: "\f38b";
}

.treeview-part .entry-name.ext-png:before {
content: "\f03e";
}

If nothing else is specified .entry-name[class*="ext-"], then the file icon \f15b is used. Every class like .dir and .ext-ts overrides the default to use a different Font Awesome 5 icon. To use brand icons for CSS and JavaScript, the font family needs to be adjusted to Font Awesome 5 Brands.

With this technique, the CSS file has a size of 1.3KB.

Appendix: Full CSS file 🔗

For reference, this is the full CSS file. The JS file I used unchanged.

.treeview-part .entry-line {
position: relative;
text-indent: -99em;
display: inline-block;
vertical-align: top;
width: 1.2em;
}

.treeview-part .entry-line:before,
.treeview-part .line-h:after
{
content: "";
position: absolute;
top: 0;
left: 50%;
width: 50%;
height: 100%;
}

.treeview-part .line-h:before,
.treeview-part .line-v:before
{
border-left: 1px solid #ccc;
}

.treeview-part .line-v-last:before {
height: 50%;
border-left: 1px solid #ccc;
border-bottom: 1px solid #ccc;
}

.treeview-part .line-h:after {
height: 50%;
border-bottom: 1px solid #ccc;
}

.treeview-part .entry-name {
position: relative;
display: inline-block;
vertical-align: top;
padding: 0 0 0 1.8em;
}

.treeview-part .entry-name:before {
content: "";
position: absolute;
top: 0;
left: 0.25em;
height: 100%;
width: 20px;
background: no-repeat 50% 50% / contain;
display: inline-block;
font-style: normal;
font-variant: normal;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
font-family: "Font Awesome 5 Free";
color: white;
font-weight: 900;
}

.treeview-part .entry-name[class*="ext-"]:before {
content: "\f15b";
}

.treeview-part .entry-name.dir:before {
content: "\f07b";
}

.treeview-part .entry-name:is(.ext-ts, .ext-js, .ext-njk, .ext-css):before {
content: "\f1c9";
}

.treeview-part .entry-name.ext-js:before {
font-family: "Font Awesome 5 Brands";
content: "\f3b9";
}

.treeview-part .entry-name.ext-css:before {
font-family: "Font Awesome 5 Brands";
content: "\f38b";
}

.treeview-part .entry-name:is(.ext-png):before {
content: "\f03e";
}