Macro Components and Reusability
**Referenced Files in This Document** - [case-study-card.njk](file://src/_includes/macros/case-study-card.njk) - [client-marquee.njk](file://src/_includes/macros/client-marquee.njk) - [testimonial-card.njk](file://src/_includes/macros/testimonial-card.njk) - [newsletter-signup.njk](file://src/_includes/macros/newsletter-signup.njk) - [cta-section.njk](file://src/_includes/macros/cta-section.njk) - [service-capability-card.njk](file://src/_includes/macros/service-capability-card.njk) - [team-flip-card.njk](file://src/_includes/macros/team-flip-card.njk) - [polling-bar.njk](file://src/_includes/macros/polling-bar.njk) - [news-article-card.njk](file://src/_includes/macros/news-article-card.njk) - [index.njk](file://src/index.njk) - [cases.njk](file://src/cases.njk) - [news.njk](file://src/news.njk) - [alliance.njk](file://src/alliance.njk) - [team.njk](file://src/team.njk) - [capabilities.njk](file://src/capabilities.njk) - [site.json](file://src/_data/site.json) - [clients.json](file://src/_data/clients.json) - [testimonials.json](file://src/_data/testimonials.json) - [homepage.json](file://src/_data/homepage.json) - [capabilitiesPage.json](file://src/_data/capabilitiesPage.json) - [pages.json](file://src/_data/pages.json) - [polling.js](file://src/_data/polling.js)Table of Contents
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
- Appendices
Introduction
This document explains the macro component system used throughout the template architecture. Macros are reusable UI building blocks implemented as Nunjucks macros and organized under src/_includes/macros/. They encapsulate common patterns such as cards, carousels, CTAs, and newsletter forms. The system supports parameterized invocation, conditional rendering, and composition across templates. Content collections and data files feed macro parameters, enabling dynamic, data-driven UI components.
Project Structure
The macro system lives under src/_includes/macros/ and is imported and invoked in various page templates. Data sources reside under src/_data/ and are consumed via collections and direct JSON objects.
graph TB
subgraph "Templates"
IDX["src/index.njk"]
CASES["src/cases.njk"]
NEWS["src/news.njk"]
ALLIANCE["src/alliance.njk"]
TEAM["src/team.njk"]
CAPS["src/capabilities.njk"]
end
subgraph "Macros"
MARQUEE["client-marquee.njk"]
SERVICE_CARD["service-capability-card.njk"]
TEAM_CARD["team-flip-card.njk"]
NEWS_CARD["news-article-card.njk"]
TEST_CARD["testimonial-card.njk"]
CTA["cta-section.njk"]
CASE_CARD["case-study-card.njk"]
POLL_BAR["polling-bar.njk"]
NEWSLETTER["newsletter-signup.njk"]
end
subgraph "Data"
SITE["src/_data/site.json"]
CLIENTS["src/_data/clients.json"]
TESTIM["src/_data/testimonials.json"]
HOME["src/_data/homepage.json"]
CAPS_PAGE["src/_data/capabilitiesPage.json"]
PAGES["src/_data/pages.json"]
POLL["src/_data/polling.js"]
end
IDX --> MARQUEE
IDX --> SERVICE_CARD
IDX --> TEAM_CARD
IDX --> NEWS_CARD
IDX --> TEST_CARD
IDX --> CTA
CASES --> CASE_CARD
CASES --> CTA
NEWS --> POLL_BAR
NEWS --> NEWS_CARD
NEWS --> NEWSLETTER
NEWS --> CTA
ALLIANCE --> MARQUEE
TEAM --> CTA
CAPS --> CTA
IDX -. uses .-> CLIENTS
IDX -. uses .-> TESTIM
IDX -. uses .-> HOME
CASES -. uses .-> PAGES
NEWS -. uses .-> POLL
NEWS -. uses .-> PAGES
ALLIANCE -. uses .-> CLIENTS
Diagram sources
- [index.njk:1-164](file://src/index.njk#L1-L164)
- [cases.njk:1-39](file://src/cases.njk#L1-L39)
- [news.njk](file://src/news.njk)
- [alliance.njk:28](file://src/alliance.njk#L28)
- [team.njk](file://src/team.njk)
- [capabilities.njk:7](file://src/capabilities.njk#L7)
- [client-marquee.njk:1-27](file://src/_includes/macros/client-marquee.njk#L1-L27)
- [service-capability-card.njk:1-11](file://src/_includes/macros/service-capability-card.njk#L1-L11)
- [team-flip-card.njk:1-18](file://src/_includes/macros/team-flip-card.njk#L1-L18)
- [news-article-card.njk:1-35](file://src/_includes/macros/news-article-card.njk#L1-L35)
- [testimonial-card.njk:1-18](file://src/_includes/macros/testimonial-card.njk#L1-L18)
- [cta-section.njk:1-18](file://src/_includes/macros/cta-section.njk#L1-L18)
- [case-study-card.njk:1-20](file://src/_includes/macros/case-study-card.njk#L1-L20)
- [polling-bar.njk:1-39](file://src/_includes/macros/polling-bar.njk#L1-L39)
- [newsletter-signup.njk:1-28](file://src/_includes/macros/newsletter-signup.njk#L1-L28)
- [clients.json](file://src/_data/clients.json)
- [testimonials.json](file://src/_data/testimonials.json)
- [homepage.json](file://src/_data/homepage.json)
- [capabilitiesPage.json](file://src/_data/capabilitiesPage.json)
- [pages.json](file://src/_data/pages.json)
- [polling.js](file://src/_data/polling.js)
Section sources
- [index.njk:1-164](file://src/index.njk#L1-L164)
- [cases.njk:1-39](file://src/cases.njk#L1-L39)
- [news.njk](file://src/news.njk)
- [alliance.njk:28](file://src/alliance.njk#L28)
- [team.njk](file://src/team.njk)
- [capabilities.njk:7](file://src/capabilities.njk#L7)
Core Components
This section documents the primary macro components and how they are used across templates.
-
case-study-card
- Purpose: Renders a single case study entry with optional quote block.
- Parameters: Accepts an item object containing image, category, client, title, content, and optional quote fields.
- Conditional rendering: Quote box appears only when quote data exists.
- Usage: Imported in cases.njk and invoked over collections.cases.
- Section sources
- [case-study-card.njk:1-20](file://src/_includes/macros/case-study-card.njk#L1-L20)
- [cases.njk:32-34](file://src/cases.njk#L32-L34)
-
client-marquee
- Purpose: Creates a horizontally scrolling marquee of client or affiliation logos.
- Parameters: items array, basePath string, speed string, grayscale boolean.
- Behavior: Validates items length, ensures trailing slash in basePath, duplicates items for seamless loop, applies grayscale class conditionally.
- Usage: Imported in index.njk and alliance.njk; invoked with clients.items and affiliations.items respectively.
- Section sources
- [client-marquee.njk:1-27](file://src/_includes/macros/client-marquee.njk#L1-L27)
- [index.njk:81](file://src/index.njk#L81)
- [index.njk:155](file://src/index.njk#L155)
- [alliance.njk:28](file://src/alliance.njk#L28)
-
testimonial-card
- Purpose: Renders a testimonial quote with author and role; supports case-study variant.
- Parameters: quote, author, role, isCaseStudy boolean.
- Conditional rendering: Switches markup based on isCaseStudy flag.
- Usage: Imported in index.njk and invoked over testimonials.items.
- Section sources
- [testimonial-card.njk:1-18](file://src/_includes/macros/testimonial-card.njk#L1-L18)
- [index.njk:97-99](file://src/index.njk#L97-L99)
-
newsletter-signup
- Purpose: Renders a newsletter subscription form in compact or full variants.
- Parameters: title, description, buttonText, variant, formId.
- Conditional rendering: Variant selection switches layout; formId is sourced from site metadata.
- Usage: Imported in news.njk and invoked with page-specific copy and defaults.
- Section sources
- [newsletter-signup.njk:1-28](file://src/_includes/macros/newsletter-signup.njk#L1-L28)
- [news.njk](file://src/news.njk)
-
cta-section
- Purpose: Renders a themed call-to-action section with optional highlighted text.
- Parameters: title, buttonText, buttonUrl, subtitle, theme, highlightText.
- Behavior: Applies theme via data attribute; highlights matching substring in title.
- Usage: Imported in index.njk, cases.njk, news.njk, team.njk, capabilities.njk.
- Section sources
- [cta-section.njk:1-18](file://src/_includes/macros/cta-section.njk#L1-L18)
- [index.njk:159](file://src/index.njk#L159)
- [cases.njk:38](file://src/cases.njk#L38)
- [news.njk](file://src/news.njk)
- [team.njk](file://src/team.njk)
- [capabilities.njk:7](file://src/capabilities.njk#L7)
-
service-capability-card
- Purpose: Renders a service capability card with image and link.
- Parameters: service object with image, image_alt, title, body, url, card_class.
- Usage: Imported in index.njk and invoked over capabilities.items.
- Section sources
- [service-capability-card.njk:1-11](file://src/_includes/macros/service-capability-card.njk#L1-L11)
- [index.njk:64-66](file://src/index.njk#L64-L66)
-
team-flip-card
- Purpose: Renders a flip-card for team member profiles with front/back views.
- Parameters: item object with image, alt, name, role, bio_short, anchor.
- Usage: Imported in index.njk and invoked over collections.teamMembers.
- Section sources
- [team-flip-card.njk:1-18](file://src/_includes/macros/team-flip-card.njk#L1-L18)
- [index.njk:117-119](file://src/index.njk#L117-L119)
-
polling-bar
- Purpose: Visualizes polling data with segments and contextual story content.
- Parameters: data object (labor_tpp, liberal_tpp, etc.), sourceText, isFallback, pages object.
- Behavior: Displays static badge when fallback mode; renders story content and statistics from pages.
- Usage: Imported in news.njk and invoked with polling data and page context.
- Section sources
- [polling-bar.njk:1-39](file://src/_includes/macros/polling-bar.njk#L1-L39)
- [news.njk](file://src/news.njk)
-
news-article-card
- Purpose: Renders a news item in carousel or expanded variant.
- Parameters: item, variant ('carousel' or default 'expanded').
- Conditional rendering: Switches markup based on variant; supports expandable content and PDF link.
- Usage: Imported in index.njk and news.njk; invoked over collections.news.
- Section sources
- [news-article-card.njk:1-35](file://src/_includes/macros/news-article-card.njk#L1-L35)
- [index.njk:136-138](file://src/index.njk#L136-L138)
Architecture Overview
The macro architecture follows a pattern:
- Templates import macros via {% import %}.
- Templates pass data from collections and data files into macro invocations.
- Macros render HTML with conditional logic and optional parameters.
- Styles and scripts are included in templates as needed.
sequenceDiagram
participant TPL as "Template (e.g., index.njk)"
participant MAC as "Macro (e.g., client-marquee.njk)"
participant DATA as "Data (e.g., clients.json)"
participant OUT as "Rendered HTML"
TPL->>MAC : import macro
TPL->>DATA : resolve collections or JSON
TPL->>MAC : invoke macro with parameters
MAC->>MAC : evaluate conditions and defaults
MAC-->>OUT : return HTML fragment
TPL-->>OUT : assemble page content
Diagram sources
- [index.njk:8-13](file://src/index.njk#L8-L13)
- [client-marquee.njk:8](file://src/_includes/macros/client-marquee.njk#L8)
- [clients.json](file://src/_data/clients.json)
Section sources
- [index.njk:1-164](file://src/index.njk#L1-L164)
- [client-marquee.njk:1-27](file://src/_includes/macros/client-marquee.njk#L1-L27)
Detailed Component Analysis
Macro Invocation Patterns
- Import and alias macros in templates to namespace invocations.
- Pass data from collections (e.g., collections.cases, collections.news) or data files (e.g., clients.items, testimonials.items).
- Use optional parameters to customize appearance and behavior.
Examples of usage:
- Index page composes multiple macros: marquee, service cards, testimonials, news cards, team cards, and CTA.
- Cases page composes case study cards and a CTA.
- News page composes polling bar, news cards, newsletter signup, and CTA.
Section sources
- [index.njk:8-13](file://src/index.njk#L8-L13)
- [index.njk:64-66](file://src/index.njk#L64-L66)
- [index.njk:81](file://src/index.njk#L81)
- [index.njk:97-99](file://src/index.njk#L97-L99)
- [index.njk:117-119](file://src/index.njk#L117-L119)
- [index.njk:136-138](file://src/index.njk#L136-L138)
- [index.njk:159](file://src/index.njk#L159)
- [cases.njk:8-9](file://src/cases.njk#L8-L9)
- [cases.njk:32-34](file://src/cases.njk#L32-L34)
- [cases.njk:38](file://src/cases.njk#L38)
Parameter Passing and Defaults
- Macros define default values for optional parameters (e.g., variant, speed, grayscale).
- Templates can override defaults inline during invocation.
- Some macros accept structured objects (e.g., service, item) and access nested properties.
Section sources
- [client-marquee.njk:8](file://src/_includes/macros/client-marquee.njk#L8)
- [newsletter-signup.njk:1](file://src/_includes/macros/newsletter-signup.njk#L1)
- [cta-section.njk:1](file://src/_includes/macros/cta-section.njk#L1)
- [service-capability-card.njk:1](file://src/_includes/macros/service-capability-card.njk#L1)
- [team-flip-card.njk:1](file://src/_includes/macros/team-flip-card.njk#L1)
- [polling-bar.njk:1](file://src/_includes/macros/polling-bar.njk#L1)
- [news-article-card.njk:1](file://src/_includes/macros/news-article-card.njk#L1)
Conditional Rendering
- Macros use conditional statements to show/hide parts of the UI based on data presence or flags.
- Examples:
- Case study quote box appears only when quote data exists.
- Marquee renders only when items array is present and non-empty.
- Testimonial variant toggles markup based on isCaseStudy flag.
- Newsletter variant switches between compact and full layouts.
Section sources
- [case-study-card.njk:11-16](file://src/_includes/macros/case-study-card.njk#L11-L16)
- [client-marquee.njk:9-27](file://src/_includes/macros/client-marquee.njk#L9-L27)
- [testimonial-card.njk:2-16](file://src/_includes/macros/testimonial-card.njk#L2-L16)
- [newsletter-signup.njk:2-26](file://src/_includes/macros/newsletter-signup.njk#L2-L26)
Creating New Macros
Steps to create a new macro:
- Add a new .njk file under src/_includes/macros/.
- Define a macro with a descriptive name and parameter list.
- Implement rendering logic with optional defaults and conditionals.
- Import the macro in target templates using {% import %}.
- Invoke the macro with appropriate data from collections or data files.
- Style the rendered HTML with dedicated CSS classes.
Reference implementations:
- [service-capability-card.njk:1-11](file://src/_includes/macros/service-capability-card.njk#L1-L11)
- [cta-section.njk:1-18](file://src/_includes/macros/cta-section.njk#L1-L18)
- [polling-bar.njk:1-39](file://src/_includes/macros/polling-bar.njk#L1-L39)
Section sources
- [service-capability-card.njk:1-11](file://src/_includes/macros/service-capability-card.njk#L1-L11)
- [cta-section.njk:1-18](file://src/_includes/macros/cta-section.njk#L1-L18)
- [polling-bar.njk:1-39](file://src/_includes/macros/polling-bar.njk#L1-L39)
Component Composition Patterns
- Compose multiple macros on a single page to build complex sections (e.g., homepage).
- Chain data transformations in templates (e.g., splitting strings, setting variables) before passing to macros.
- Use theme attributes and variants to adapt macros for different contexts.
Evidence:
- Index page composes marquee, service cards, testimonials, news cards, team cards, and CTA.
- Cases page composes case study cards and a CTA.
- News page composes polling bar, news cards, newsletter signup, and CTA.
Section sources
- [index.njk:52-74](file://src/index.njk#L52-L74)
- [index.njk:77-82](file://src/index.njk#L77-L82)
- [index.njk:84-107](file://src/index.njk#L84-L107)
- [index.njk:109-121](file://src/index.njk#L109-L121)
- [index.njk:123-146](file://src/index.njk#L123-L146)
- [index.njk:149-156](file://src/index.njk#L149-L156)
- [index.njk:159](file://src/index.njk#L159)
- [cases.njk:30-36](file://src/cases.njk#L30-L36)
- [cases.njk:38](file://src/cases.njk#L38)
- [news.njk](file://src/news.njk)
Relationship Between Macros and Data Sources
- Collections: macros consume Eleventy collections (e.g., collections.cases, collections.news, collections.teamMembers).
- Data files: macros receive data from JSON files (e.g., clients.json, testimonials.json) or JavaScript data sources (e.g., polling.js).
- Page-level data: macros use page-specific content from data files (e.g., pages.json, capabilitiesPage.json, homepage.json).
Examples:
- Index page passes clients.items to marquee and testimonials.items to testimonial cards.
- Cases page iterates over collections.cases and passes each item to case-study-card.
- News page uses polling.js for data and pages.json for contextual content.
Section sources
- [index.njk:81](file://src/index.njk#L81)
- [index.njk:97-99](file://src/index.njk#L97-L99)
- [index.njk:32-34](file://src/cases.njk#L32-L34)
- [news.njk](file://src/news.njk)
- [clients.json](file://src/_data/clients.json)
- [testimonials.json](file://src/_data/testimonials.json)
- [homepage.json](file://src/_data/homepage.json)
- [capabilitiesPage.json](file://src/_data/capabilitiesPage.json)
- [pages.json](file://src/_data/pages.json)
- [polling.js](file://src/_data/polling.js)
Dependency Analysis
This section maps macro usage across templates and highlights data dependencies.
graph LR
IDX["index.njk"] --> MAR["client-marquee.njk"]
IDX --> SVC["service-capability-card.njk"]
IDX --> TFC["team-flip-card.njk"]
IDX --> NAC["news-article-card.njk"]
IDX --> TST["testimonial-card.njk"]
IDX --> CTA["cta-section.njk"]
CASES["cases.njk"] --> CSC["case-study-card.njk"]
CASES --> CTA
NEWS["news.njk"] --> POLL["polling-bar.njk"]
NEWS --> NAC
NEWS --> NS["newsletter-signup.njk"]
NEWS --> CTA
ALLIANCE["alliance.njk"] --> MAR
TEAM["team.njk"] --> CTA
CAPS["capabilities.njk"] --> CTA
Diagram sources
- [index.njk:8-13](file://src/index.njk#L8-L13)
- [cases.njk:8-9](file://src/cases.njk#L8-L9)
- [news.njk](file://src/news.njk)
- [alliance.njk:28](file://src/alliance.njk#L28)
- [team.njk](file://src/team.njk)
- [capabilities.njk:7](file://src/capabilities.njk#L7)
Section sources
- [index.njk:1-164](file://src/index.njk#L1-L164)
- [cases.njk:1-39](file://src/cases.njk#L1-L39)
- [news.njk](file://src/news.njk)
- [alliance.njk:28](file://src/alliance.njk#L28)
- [team.njk](file://src/team.njk)
- [capabilities.njk:7](file://src/capabilities.njk#L7)
Performance Considerations
- Lazy loading: All img tags include loading="lazy" to defer offscreen image decoding.
- Minimal DOM: Marquee duplicates items to enable seamless looping without extra JS.
- Efficient iteration: Macros iterate over pre-built collections and arrays; avoid heavy computations inside loops.
- Asset paths: Macros accept basePath parameters to reduce duplication and improve cacheability.
- Conditional rendering: Only renders sections when data is present, reducing unnecessary DOM nodes.
Section sources
- [case-study-card.njk:4](file://src/_includes/macros/case-study-card.njk#L4)
- [client-marquee.njk:16](file://src/_includes/macros/client-marquee.njk#L16)
- [testimonial-card.njk:1](file://src/_includes/macros/testimonial-card.njk#L1)
- [newsletter-signup.njk:6](file://src/_includes/macros/newsletter-signup.njk#L6)
- [service-capability-card.njk:3](file://src/_includes/macros/service-capability-card.njk#L3)
- [team-flip-card.njk:5](file://src/_includes/macros/team-flip-card.njk#L5)
- [news-article-card.njk:12](file://src/_includes/macros/news-article-card.njk#L12)
Troubleshooting Guide
Common issues and resolutions:
- Missing data for marquee: Ensure items array is populated; marquee renders only when items exist.
- Empty testimonials or case studies: Verify collections are built and data files are correctly formatted.
- Form submission failures: Confirm formId is available in site metadata; newsletter macro uses site.convertkit_form_id.
- Polling bar fallback: When isFallback is true, macro displays a static data badge; ensure polling data is properly loaded.
- Variant mismatches: Ensure variant parameter matches expected values ('carousel' vs default for news-article-card).
Section sources
- [client-marquee.njk:9-27](file://src/_includes/macros/client-marquee.njk#L9-L27)
- [newsletter-signup.njk:1](file://src/_includes/macros/newsletter-signup.njk#L1)
- [polling-bar.njk:5](file://src/_includes/macros/polling-bar.njk#L5)
- [news-article-card.njk:1](file://src/_includes/macros/news-article-card.njk#L1)
Conclusion
The macro component system provides a scalable, maintainable way to compose UI across the site. By encapsulating common patterns, supporting optional parameters and conditionals, and integrating seamlessly with Eleventy’s collections and data files, macros enable rapid development and consistent design. Following the composition patterns and performance practices outlined here ensures reliable, high-quality implementations.
Appendices
Best Practices for Macro Organization and Naming
- Name macros descriptively (e.g., testimonial-card.njk, newsletter-signup.njk).
- Keep macros focused on a single responsibility.
- Use consistent parameter naming and defaults.
- Group related macros under src/_includes/macros/.
Section sources
- [testimonial-card.njk:1](file://src/_includes/macros/testimonial-card.njk#L1)
- [newsletter-signup.njk:1](file://src/_includes/macros/newsletter-signup.njk#L1)
Practical Examples Index
- Creating a new macro: Use service-capability-card.njk as a minimal template.
- Importing macros: See index.njk imports for examples.
- Passing data: Observe how collections and data files feed macro parameters.
Section sources
- [service-capability-card.njk:1-11](file://src/_includes/macros/service-capability-card.njk#L1-L11)
- [index.njk:8-13](file://src/index.njk#L8-L13)
- [index.njk:32-34](file://src/cases.njk#L32-L34)