@data-content : The Dynamic Content Attribute
The data-content attribute enables dynamic content injection into elements at data binding time in Scryber PDF documents. It allows you to specify content as a string that will be parsed and inserted into the element, replacing or augmenting existing content based on the data-content-action setting.
Summary
The data-content attribute provides a mechanism for dynamically generating and inserting content into elements during the data binding phase. Unlike static content declared in the template, data-content evaluates at runtime, allowing you to:
- Generate content from bound data values
- Insert dynamically constructed HTML/XHTML markup
- Replace element content conditionally
- Prepend or append dynamic content to existing elements
- Create inline templates without nested element structures
This attribute is particularly useful when:
- Content structure varies based on data
- You need to generate markup programmatically
- Template content comes from external sources
- You want to avoid deeply nested template structures
Usage
The data-content attribute accepts a string value containing HTML/XHTML markup or plain text. The content is parsed according to the document’s default parser or the MIME type specified in data-content-type.
Basic Syntax
<!-- Simple text content -->
<label data-content="">Default Name</label>
<!-- HTML markup content -->
<div data-content="<p>Hello <strong></strong></p>"></div>
<!-- Dynamic content from bound expression -->
<span data-content=""></span>
Content Actions
The data-content-action attribute controls how the content is inserted:
| Action | Behavior | Default |
|---|---|---|
append |
Add after existing content | No (except for VisualComponent) |
prepend |
Add before existing content | No |
replace |
Replace all existing content | Yes (for most components) |
<!-- Replace existing content (default for labels) -->
<label data-content="">Old text</label>
<!-- Append to existing content -->
<div data-content="<p></p>" data-content-action="append">
<p>Existing content stays here</p>
</div>
Supported Elements
The data-content attribute is supported on the following elements:
Primary Support
<label>- Text labels with dynamic content (HTMLLabel)<template>- Template elements with inline content definition (HTMLTemplate)<frame>- Frame elements for document assembly (HTMLFrame)
General Support
- All
VisualComponentdescendants - Any visual element that inherits from VisualComponent
Implementation Details
HTMLLabel: Content is set directly and rendered as text literal during pre-layout phase.
HTMLTemplate: Content is parsed as a template and used instead of child elements.
HTMLFrame: Content is parsed as HTML document and used for frame content.
VisualComponent: Content is parsed according to MIME type and inserted per the specified action.
Binding Values
Expression Evaluation
The data-content attribute value is evaluated during data binding, supporting:
<!-- Direct property binding -->
<label data-content=""></label>
<!-- Legacy syntax -->
<label data-content="{@:model.userName}"></label>
<!-- String concatenation -->
<label data-content=""></label>
<!-- Conditional content -->
<label data-content=""></label>
Content Type Specification
Use data-content-type to specify the MIME type of the content:
<!-- HTML content (default) -->
<div data-content="<p>HTML content</p>" data-content-type="text/html"></div>
<!-- XHTML content -->
<div data-content="<div xmlns='http://www.w3.org/1999/xhtml'><p>XHTML</p></div>"
data-content-type="application/xhtml+xml"></div>
<!-- Plain text -->
<div data-content="" data-content-type="text/plain"></div>
Markup Requirements
Content must be well-formed according to the specified type:
For HTML/XHTML:
- Must be valid markup
- Elements must be properly closed
- Attributes must be quoted
- Namespace declarations required for XHTML
For Plain Text:
- No parsing applied
- Rendered as literal text
- Special characters handled automatically
Notes
Content Parsing
-
Parse Timing: Content is parsed and inserted during the data binding phase, after all binding expressions are evaluated.
-
Parser Selection: The document’s parser for the specified MIME type is used. If no type is specified, the default content MIME type is used.
-
Validation: In strict conformance mode, parse errors will throw exceptions. In lax mode, warnings are logged.
-
Component Requirements: Parsed content must result in compatible components for the target element.
Label-Specific Behavior
For <label> elements:
- Content is set as simple text during pre-layout
- Existing content is cleared
- No HTML parsing occurs
- Most efficient for simple text replacement
- Always replaces existing content
Template-Specific Behavior
For <template> elements:
- Content defines the template to repeat
- Takes precedence over child elements
- Must contain valid HTML/XHTML
- Creates parsable template generator
- Useful for dynamic template definition
Frame-Specific Behavior
For <frame> elements:
- Content must be a complete HTML document
- Parsed as HTMLDocument component
- Used for document assembly scenarios
- Initialized and data-bound after parsing
- Only accepts full XHTML documents
Content Action Behavior
The default data-content-action varies by component:
- Label: Always replaces (action ignored)
- Template: Always replaces (action ignored)
- Frame: Always replaces (action ignored)
- VisualComponent: Default is
append
Performance Considerations
- Parsing content has overhead; cache when possible
- Use
data-style-identifierwith repeated patterns - Avoid complex markup in large iterations
- Consider building content in code for complex scenarios
- Pre-process and simplify content when feasible
Security Considerations
- Content is parsed and executed in the document context
- Validate external content sources
- Sanitize user-provided content
- Be cautious with dynamic code generation
- Use strict conformance mode for validation
Examples
1. Simple Text Replacement in Label
Replace label text with bound data:
<!-- Model: { userName: "John Smith" } -->
<label data-content="">Loading...</label>
<!-- Result: John Smith -->
2. Dynamic Formatted Text
Generate formatted content from data:
<!-- Model: { firstName: "Jane", lastName: "Doe", title: "Dr." } -->
<label data-content="">
Name Placeholder
</label>
<!-- Result: Dr. Jane Doe -->
3. Conditional Content Display
Show different content based on conditions:
<!-- Model: { isActive: true, status: "Premium" } -->
<label data-content="">
Status Unknown
</label>
<!-- Result: Active - Premium -->
4. Dynamic HTML Content in Div
Insert formatted HTML markup:
<!-- Model: { productName: "Widget Pro", price: 29.99, inStock: true } -->
<div data-content="<div><strong></strong><br/>Price: $<br/><em></em></div>"></div>
<!-- Renders formatted product info -->
5. Inline Template Content
Define template content inline without nested elements:
<!-- Model: { items: [{name: "A"}, {name: "B"}] } -->
<template data-bind=""
data-content="<div style='padding:5pt; border:1pt solid #ccc;'></div>">
</template>
<!-- Generates: -->
<!-- <div>A</div> -->
<!-- <div>B</div> -->
6. Appending Dynamic Content
Add content after existing elements:
<div data-content="<p><em></em></p>" data-content-action="append">
<p>Main content appears here first.</p>
</div>
<!-- Results in main content followed by disclaimer -->
7. Prepending Header Content
Add content before existing elements:
<div data-content="<h2></h2>" data-content-action="prepend">
<p>This paragraph will appear after the title.</p>
</div>
<!-- Results in title followed by paragraph -->
8. Complex Multi-Line HTML Content
Generate complex markup structure:
<!-- Model: { user: {name: "Alice", role: "Admin", department: "IT"} } -->
<div data-content="<div style='border: 2pt solid #336699; padding: 10pt;'>
<h3 style='margin: 0; color: #336699;'></h3>
<div style='margin-top: 5pt;'>
<strong>Role:</strong> <br/>
<strong>Department:</strong>
</div>
</div>">
</div>
9. Dynamic Table Content Generation
Create table structure dynamically:
<!-- Model: { columns: ["ID", "Name", "Status"], hasData: true } -->
<div data-content="<table style='width:100%;'>
<thead>
<tr>
<template data-bind=''>
<th></th>
</template>
</tr>
</thead>
<tbody>
<tr><td colspan='3' style='text-align:center;'>
</td></tr>
</tbody>
</table>">
</div>
10. Conditional Section Inclusion
Include entire sections conditionally:
<!-- Model: { showWarning: true, warningMessage: "Important notice" } -->
<div data-content="">
</div>
<!-- Only renders if showWarning is true -->
11. List Generation with Dynamic Styling
Create styled list items:
<!-- Model: { priority: "high", tasks: ["Task A", "Task B"] } -->
<template data-bind=""
data-content="<div style='padding: 8pt; margin: 5pt; border-left: 3pt solid ;'></div>">
</template>
<!-- Each task gets colored border based on priority -->
12. Placeholder with Fallback Content
Show dynamic content or fallback:
<!-- Model: { description: null } -->
<div data-content="">
Loading...
</div>
<!-- Shows fallback when description is null -->
13. Frame with Dynamic Document Content
Assemble documents dynamically:
<!-- Model: { reportContent: "<html>...</html>" } -->
<frameset>
<frame src="header.html"></frame>
<frame data-content=""></frame>
<frame src="footer.html"></frame>
</frameset>
<!-- Inserts dynamic report between header and footer -->
14. Localized Content Injection
Insert locale-specific content:
<!-- Model: { locale: "es", welcomeMessages: {en: "Welcome", es: "Bienvenido"} } -->
<label data-content="">
Welcome
</label>
<!-- Shows: Bienvenido -->
15. Rich Text with Embedded Bindings
Create complex formatted content with multiple bindings:
<!-- Model: { order: {id: 1234, date: "2024-10-13", customer: "Acme Corp", total: 1500.00} } -->
<div data-content="<div style='padding: 15pt; border: 2pt solid #336699;'>
<h2 style='margin: 0 0 10pt 0; color: #336699;'>Order Confirmation</h2>
<div style='margin-bottom: 5pt;'><strong>Order Number:</strong> </div>
<div style='margin-bottom: 5pt;'><strong>Date:</strong> </div>
<div style='margin-bottom: 5pt;'><strong>Customer:</strong> </div>
<div style='margin-top: 10pt; padding-top: 10pt; border-top: 1pt solid #ccc;'>
<strong>Total:</strong> <span style='font-size: 14pt; color: #336699;'>$</span>
</div>
</div>">
</div>
16. Template with Alternate Content Definition
Define template behavior inline:
<!-- Model: { items: [{type: "A", name: "Item 1"}, {type: "B", name: "Item 2"}] } -->
<template data-bind=""
data-content="<div style='padding: 10pt; background-color: ; margin-bottom: 5pt;'>
<strong>:</strong>
</div>">
</template>
<!-- Type A items get blue background, Type B get purple -->
See Also
- data-content-type attribute - Specify content MIME type
- data-content-action attribute - Control content insertion
- label element - Label element reference
- template element - Template element reference
- frame element - Frame element reference
- Data Binding - Data binding overview
- Expressions - Expression syntax guide