Skip to content
CMO & CTO
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

  • Digital Experience
    • Experience Strategy
    • Experience-Driven Commerce
    • Multi-Channel Experience
    • Personalization & Targeting
    • SEO & Performance
    • User Journey & Behavior
  • Marketing Technologies
    • Analytics & Measurement
    • Content Management Systems
    • Customer Data Platforms
    • Digital Asset Management
    • Marketing Automation
    • MarTech Stack & Strategy
    • Technology Buying & ROI
  • Software Engineering
    • Software Engineering
    • Software Architecture
    • General Software
    • Development Practices
    • Productivity & Workflow
    • Code
    • Engineering Management
    • Business of Software
    • Code
    • Digital Transformation
    • Systems Thinking
    • Technical Implementation
  • About
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

Macros and Includes: Building Reusable Blocks

Posted on September 21, 2010 By Luis Fernandez

FreeMarker macros and includes sound like small features, but they rescue your templates from copy paste chaos. If you are shipping landing pages, transactional email, and a bunch of JSP views, you know the pain. Same button in five places, slightly different markup, one broken change ruins a campaign. With the web buzzing about HTML5, IE9 beta on the news, and jQuery everywhere, we can still keep our server side templates tidy. This is a short field guide to reusable blocks with FreeMarker that will age well.

Problem framing

macros and includes. That gives you one source of truth, fewer bugs, and faster changes.

Three case walkthrough

Case one. A button macro you can drop anywhere

This is the poster child of reuse. Define a macro once, call it wherever you need a call to action. Want to switch class names or add rel attributes later Better to change one file than twenty.

<#-- file: macros/ui.ftl -->
<#macro button label url className="btn primary" rel="nofollow">
  <a href="${url?html}" class="${className?html}" rel="${rel?html}">${label?html}</a>
</#macro>

<#-- usage -->
<#import "/macros/ui.ftl" as ui />

<p>
  <@ui.button label="Get the guide" url="https://example.com/guide" />
</p>

Now the next time marketing wants rounded corners or a different class, you touch one macro.

Case two. Includes for headers and footers with simple switches

Put shared chrome in partials and include them. Add a tiny switch for campaigns or locales. This keeps templates readable while still flexible.

<#-- file: pages/landing.ftl -->
<#if campaign == "fall">
  <#include "/partials/header_fall.ftl" />
<#else>
  <#include "/partials/header.ftl" />
</#if>

<main>
  <h2>Limited offer</h2>
  <p>Save your seat for the webinar.</p>
</main>

<#include "/partials/footer.ftl" />

Includes are boring on purpose. That is the point. One header everywhere. Your QA and your future self will thank you.

Case three. A marketing macro to add tracking without tears

Stop hand typing utm params. Put the logic in a macro and keep your reports clean. This also prevents weird escaping bugs when a title sneaks into a query string.

<#-- file: macros/marketing.ftl -->
<#macro trackedLink url text campaign medium source>
  <#assign u = url + "?utm_campaign=" + campaign?url + "&utm_medium=" + medium?url + "&utm_source=" + source?url />
  <a href="${u}">${text?html}</a>
</#macro>

<#-- usage -->
<#import "/macros/marketing.ftl" as m />

<p>
  <@m.trackedLink
    url="https://example.com/signup"
    text="Sign up"
    campaign="fall"
    medium="email"
    source="newsletter"
/>
</p>

Now the team can change naming for sources in one place and re publish. Clean and safe.

Objections and replies

  • I can just copy and paste. You can, but then you will fix five files at two in the morning. Macros and includes cut that cost to one edit.
  • Macros are hard to debug. FreeMarker errors point to line numbers inside macros. Keep macros small, and name them clearly. Logging template exceptions in your servlet helps too.
  • Includes will slow down the page. FreeMarker caches parsed templates by default. Set template update delay to a sane value in dev and in prod you get fast loads.
  • Designers will hate template tags. Agree on a small set of macros with friendly names. Fewer tags in the file than repeated markup blocks makes files easier to read.
  • We already have JSP taglibs. Great. Use both. Taglibs for heavy server side work, FreeMarker macros for tidy view snippets.

Action steps you can ship this week

  • Create a folder for shared templates, for example /macros and /partials.
  • Add a tiny ui.ftl with a button macro and start replacing duplicate buttons.
  • Move your header and footer to /partials and include them from pages.
  • Add one marketing macro for tracking links, and stop hand writing query params.
  • Pick names and conventions. Keep macro names short and human. Add defaults for optional params.
  • Turn on template caching and set template update delay in your FreeMarker config in dev and prod.
  • Review templates with the team. Mark places that deserve a macro. Aim for fewer tags and cleaner files.

That is it. Reusable blocks with macros and includes make your templates calm. You spend less time fixing the same thing everywhere and more time shipping. If you are juggling Spring MVC or Struts and trying the new IE9 beta in the same day, you want this kind of boring power in your stack.

Productivity & Workflow Software Engineering

Post navigation

Previous post
Next post
  • Digital Experience (94)
    • Experience Strategy (19)
    • Experience-Driven Commerce (5)
    • Multi-Channel Experience (9)
    • Personalization & Targeting (21)
    • SEO & Performance (10)
  • Marketing Technologies (92)
    • Analytics & Measurement (14)
    • Content Management Systems (45)
    • Customer Data Platforms (4)
    • Digital Asset Management (8)
    • Marketing Automation (6)
    • MarTech Stack & Strategy (10)
    • Technology Buying & ROI (3)
  • Software Engineering (310)
    • Business of Software (20)
    • Code (30)
    • Development Practices (52)
    • Digital Transformation (21)
    • Engineering Management (25)
    • General Software (82)
    • Productivity & Workflow (30)
    • Software Architecture (85)
    • Technical Implementation (23)
  • 2025 (12)
  • 2024 (8)
  • 2023 (18)
  • 2022 (13)
  • 2021 (3)
  • 2020 (8)
  • 2019 (8)
  • 2018 (23)
  • 2017 (17)
  • 2016 (40)
  • 2015 (37)
  • 2014 (25)
  • 2013 (28)
  • 2012 (24)
  • 2011 (30)
  • 2010 (42)
  • 2009 (25)
  • 2008 (13)
  • 2007 (33)
  • 2006 (26)

Ab Testing Adobe Adobe Analytics Adobe Target AEM agile-methodologies Analytics architecture-patterns CDP CMS coding-practices content-marketing Content Supply Chain Conversion Optimization Core Web Vitals customer-education Customer Data Platform Customer Experience Customer Journey DAM Data Layer Data Unification documentation DXP Individualization java Martech metrics mobile-development Mobile First Multichannel Omnichannel Personalization product-strategy project-management Responsive Design Search Engine Optimization Segmentation seo spring Targeting Tracking user-experience User Journey web-development

©2025 CMO & CTO | WordPress Theme by SuperbThemes