Persistent Include Trap

46 views
Skip to first unread message

Neil Faiman

unread,
May 31, 2026, 12:16:34 PM (7 days ago) May 31
to BBEdit Talk Mailing List
Given that my web development strategy has been built on BBEdit persistent include files for years, I can’t believe it’s taken this long for me to discover this trap.

I have a persistent include file named Letterhead-html5:

<header>

<a href="#RELATIVE#index.html">

<img src="#RELATIVE#Imgs/town_hall_logo.gif" alt="" width="80" height="78">

<p>Town of Wilton, NH</p>

<p>#TITLE#</p>

</a>

</header>


Here is the top of my web page:

<!DOCTYPE html>

<html lang="en-US">

<head>

<title>1989 Wilton Zoning Ordinance</title>


And later in the page I have:

<!-- #bbinclude "Letterhead-html5" #TITLE#="Zoning Ordinance (1989)" -->

<!-- end bbinclude -->


When I update the page, this is what I end up with:

<!-- #bbinclude "Letterhead-html5" 1989 Wilton Zoning Ordinance="Zoning Ordinance (1989)" -->

<header>

<a href="../../index.html">

<img src="../../Imgs/town_hall_logo.gif" alt="" width="80" height="78">

<p>Town of Wilton, NH</p>

<p>Zoning Ordinance (1989)</p>

</a>

</header>

<!-- end bbinclude -->


Look what’s happened to the #bbinclude directive. The parameter name, “#TITLE#”, has been replaced by the page title, “1989 Wilton Zoning Ordinance”, so the next update of this page will fail with a malformed persistent include.

Of course, this is documented behavior. #TITLE# is a placeholder name, and when you update a page, placeholders are replaced by their values. It doesn’t matter if the #TITLE# is being used as a parameter name in a persistent include.It’s a placeholder, and it gets replaced by the document title.

So let this be a warning to you: double-check the parameter names you use for your persistent includes. If one of them matches one of the 40+ builtin placeholders, you will have a nasty surprise when you update your document.

Cheers,
Neil Faiman

p.s. Since I’ve been using this particular include file for almost a decade, how did take this long for the trap to spring? Well, up until now, I’ve only been including it indirectly from other include files. For example, Ordinance Section Header looks like this:

<!DOCTYPE html>

<html lang="en-US">

<head>

<title>Wilton, NH Zoning Ordinance Section #SECTION#: #SECTNAME#</title>

<meta name="description" content="Wilton, NH Zoning Ordinance, Section #SECTION#, #SECTNAME#">

<meta name="keywords" content="Zoning, ZBA, Wilton, New Hampshire, Ordinance, Zoning Ordinance">

#bbinclude "Common Head Elements-html5"

<!-- #bbinclude "Ordinance Next and Prev.pl" #mode#="header" -->

<!-- end bbinclude -->

<link rel="Stylesheet" href="#RELATIVE#ordinance/definition_popup-2.css" type="text/css">

<script src="#RELATIVE#ordinance/definition_popup-3.js"></script>

#CUSTOM#

</head>

<body class="ordinance">

<iframe id="definitions_frame" src="./ordinance_03.html" hidden></iframe>

<!-- #bbinclude "Letterhead-html5" #TITLE#="Zoning Ordinance (#VERSION#)" --><!-- end bbinclude -->

<nav class="breadcrumbs" aria-label="Breadcrumbs">

<ul>

<!-- #bbinclude "Ordinance Breadcrumbs.swift" --><!-- end bbinclude -->

</ul>

</nav>

#bbinclude "Ordinance Disclaimer"

<!-- #bbinclude "Ordinance Version.swift" --><!-- end bbinclude -->

<section role="main" id="main_content">

<h1><span class="number">#SECTION#.0</span>

<span class="label">#SECTNAME#</span></h1>


So the persistent include with the #TITLE# parameter never actually appeared in a page source. Yesterday I was the first time I included the letterhead include file directly in a page.
Reply all
Reply to author
Forward
0 new messages