Document Configuration
Configure metadata, logging, error handling, security and performance for production-ready documents.
Table of Contents
- Document Properties - Title, author, subject and keywords
- Logging - Log levels, collecting entries, custom log handlers
- Error Handling & Conformance - Strict and Lax modes, handling failures
- Security - Encryption, passwords, permissions
- Optimization & Performance - File size, compression, caching, scaling
- Production & Deployment - Production setup, monitoring, troubleshooting
Overview
Most configuration can be done in two places:
- In the template -
<title>,<meta>tags and the<?paperwork ?>processing instruction. The template carries its own settings wherever it is used. - In code - on the document builder, or on an engine
Documentthat is parsed, configured and passed to the builder withWithLayout(doc). See The Engine Document.
Settings that apply to every document - fonts, image caching, output compression, logging - go in the application’s configuration. See Configuration Structure.
Quick Example
In the template:
<?paperwork parser-mode='Lax' ?>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
<title>Invoice {{model.number}}</title>
<meta name='author' content='Acme Corporation' />
<meta name='description' content='Invoice for {{model.customerName}}' />
<meta name='keywords' content='invoice, {{model.number}}' />
<meta name='print-restrictions' content='printing, accessibility' />
</head>
<body>
...
</body>
</html>
In code:
using Paperwork;
using Scryber;
using Scryber.Components;
using Scryber.Logging;
using Scryber.PDF.Secure;
using var factory = PaperworkFactory.Create().Build();
using var doc = Document.ParseDocument("invoice.html");
// Collect any warnings or errors
var log = new CollectorTraceLog(TraceRecordLevel.Warnings, "Invoice", autostart: true);
doc.AddTraceLog(log);
// Protect the restrictions with an owner password
doc.RenderOptions.PasswordProvider = new DocumentPasswordProvider(ownerPassword);
var result = await factory.NewDocument()
.WithLayout(doc)
.WithData("model", invoice)
.BuildAsync();
foreach (var entry in log)
Console.WriteLine($"{entry.Level}: {entry.Message}");
What You’ll Learn
1. Document Properties
- Title, author, subject and keywords from the template
- Setting properties in code
- Bound values in metadata
2. Logging
- Log levels
- Appending the log to the document
- Collecting log entries in code
- Custom log handlers
3. Error Handling & Conformance
- Strict and Lax conformance modes
- Handling generation failures with
BuildAsync - Graceful degradation for missing data
5. Security
- Restrictions in the template
- Owner and user passwords
- Permissions in code
6. Optimization & Performance
- File size
- Image and font choices
- Re-using the factory
- Scaling generation
7. Production & Deployment
- Production configuration
- Monitoring and logging
- Common deployment scenarios
- Troubleshooting
Prerequisites
- Complete Getting Started
- Read The Factory and The Document Builder
Key Concepts
Conformance Modes
Strict:
- Unknown elements, attributes and invalid values are errors
- Best for templates you control and test
Lax (the default):
- Unknown content is skipped and logged
- Best for templates from other sources
Logging Levels
Verbose → Everything (debugging)
Messages → Informational messages
Warnings → Potential issues
Errors → Critical problems
Off → No logging
Tips for Success
- Log everything in development -
WithLogLevel(PaperworkRequestLogOption.Verbose) - Collect warnings in production - and send them to your logging system
- Use Lax mode for templates you don’t control
- Use Strict mode while developing your own templates
- Always set a title - PDF viewers show it instead of the file name
- Set an owner password whenever you restrict a document
- Re-use one factory for the whole application
Common Pitfalls
❌ Ignoring the result
var result = await factory.NewDocument()
.WithLayoutFile("invoice.html")
.BuildAsync();
await File.WriteAllBytesAsync("invoice.pdf", result.Document.Binary);
âś… Check for success
if (!result.Success)
{
_logger.LogError("Invoice failed: {Message} {Error}", result.Message, result.Error);
return;
}
await File.WriteAllBytesAsync("invoice.pdf", result.Document.Binary);
Or use SaveAsync or BuildBytesAsync, which throw an exception when generation fails.
Next Steps
Start with Document Properties.
Jump to specific topics:
- Logging for diagnostic information
- Security for protection
- Optimization & Performance for production
Related Series:
- Getting Started - Basic concepts
- Practical Applications - Real-world examples
Begin configuration → Document Properties