The Content Tag
The <?content()?> tag is used to embed managed content within your APD templates. It provides a powerful way to separate page structure from page content.
Basic Syntax
<?content(content-name)?>
Where content-name is the unique identifier of the content item.
How It Works
When APD encounters a <?content()?> tag:
- Looks up content by name
- Checks language variants
- Verifies security profile
- Converts Markdown to HTML (if needed)
- Inserts the resulting HTML
Examples
Simple Content Inclusion
<!DOCTYPE html>
<html>
<body>
<header>
<?content(site-header)?>
</header>
<main>
<?content(home-welcome)?>
</main>
<footer>
<?content(site-footer)?>
</footer>
</body>
</html>
Article Page
<article>
<h1><?content(article-title)?></h1>
<div class="content">
<?content(article-body)?>
</div>
</article>
FAQ Page
<div class="faq">
<h1>Frequently Asked Questions</h1>
<?content(faq-general)?>
<h2>Ordering</h2>
<?content(faq-ordering)?>
<h2>Shipping</h2>
<?content(faq-shipping)?>
</div>
Language Handling
Automatic Language Selection
APD automatically selects the appropriate language:
<!-- Will display content in user's language if available -->
<?content(welcome-message)?>
Language Priority
- User's session language: If user has set a preference
- Default language: Falls back to language = 0
Creating Language Variants
- Create base content: "welcome-message" with Language = 0
- Create variant: "welcome-message" with Language = 1031 (German)
- APD serves appropriate version automatically
Security
Profile-Restricted Content
Content can be restricted by security profile:
<!-- Only users with PREMIUM profile will see this -->
<?content(premium-features)?>
If user doesn't have the required profile, the content is not displayed (no error, just empty).
Combining with Template Security
<?profile(PREMIUM)?>
<div class="premium-section">
<?content(premium-content)?>
</div>
<?endif?>
Dynamic Content Names
Using Expression Functions
You can pass an expression as the content name — <?content?> accepts any expression in its parameter, so Parm(), field(), and concatenation with .. all work. You just cannot nest a <??> tag inside the parameter.
<!-- From a URL parameter (the "page" query string) -->
<?content(Parm('page'))?>
<!-- Prefix + URL parameter -->
<?content('help-'..Parm('topic'))?>
<!-- From a field in an open table -->
<?content(field("APD Page Content Hgd","Content Name"))?>
Using the Reserved content URL Parameter
APD also supports a built-in dynamic mode: when <?content?> is called without arguments and the URL contains a content query parameter, APD uses that parameter as the content name automatically. The same applies to <?contentraw?> and <?contenttitle?>.
<!-- URL: ?action=ARTICLE&content=getting-started
APD reads the "content" parameter and resolves it for you. -->
<?content?>
Content Not Found
Behavior
When content is not found:
- No error is thrown
- Empty string is inserted
- Page continues to render
Defensive Pattern
<?content(optional-banner)?>
<!-- If banner content doesn't exist, nothing shows -->
With Fallback
APD has no ContentExists tag — <?content?> simply emits an empty string when no matching content is found, so for optional content you can just call the tag and let it produce nothing. If you need a visible fallback, wrap the call in surrounding HTML that always renders (e.g. a heading + the tag) so the page still looks intentional even when the content row is missing.
Markdown Processing
Automatic Conversion
When content style is Markdown:
- Markdown is parsed
- Converted to HTML
- Inserted into page
Supported Markdown
| Syntax | Output |
|---|---|
# Heading |
<h1>Heading</h1> |
bold |
<strong>bold</strong> |
italic |
<em>italic</em> |
- item |
<ul><li>item</li></ul> |
text |
<a href="url">text</a> |
|
<code>code</code> |
HTML Content
Raw HTML
When content style is HTML:
- HTML is inserted directly
- No processing applied
- Full control over output
Use Cases for HTML
- Complex layouts
- Custom styling
- Interactive elements
- Third-party embeds
Styling Content
CSS for Content
Add CSS targeting content areas:
.content-area h1 {
color: #333;
font-size: 24px;
}
.content-area p {
line-height: 1.6;
}
.content-area ul {
padding-left: 20px;
}
Content Wrapper
Wrap content for styling:
<div class="content-area">
<?content(my-content)?>
</div>
Navigation with Content
Content as Landing
Use content parameter in URL:
?content=about-us
This displays the content within its host action's template.
Internal Links
Link to other content:
See our [Privacy Policy](?content=privacy-policy) for details.
Best Practices
Naming Conventions
- Use lowercase with hyphens:
about-us,faq-shipping - Group related content:
help-getting-started,help-orders - Be descriptive but concise
Organization
General:
- site-header
- site-footer
- about-us
Products:
- product-overview
- product-features
Help:
- help-getting-started
- help-account
- help-orders
Separation of Concerns
- Templates: Structure and logic
- Content: Text and articles
- CSS: Styling
- JavaScript: Behavior
Troubleshooting
Content Not Displaying
- Verify content name is correct
- Check content exists in Content List
- Verify security profile matches
- Check language settings
Wrong Language Shown
- Verify user's language preference
- Check language variants exist
- Ensure correct language IDs used
Markdown Not Converting
- Verify content style is "Markdown"
- Check for syntax errors
- Try simpler Markdown