270 lines
7.5 KiB
Markdown
270 lines
7.5 KiB
Markdown
# Embedded Templates Feature
|
|
|
|
## Overview
|
|
|
|
The embedded templates feature allows templates to be stored within project files (.ppz) so they travel with the document. When loading projects, embedded templates take priority over local filesystem templates, ensuring projects can be opened on any machine without missing custom templates.
|
|
|
|
## Key Benefits
|
|
|
|
✓ **Portability**: Templates travel with project files
|
|
✓ **Self-contained**: No dependency on local template files
|
|
✓ **Priority**: Embedded templates override filesystem templates
|
|
✓ **Automatic**: Templates are auto-embedded when used
|
|
✓ **Backward Compatible**: Projects without embedded templates work as before
|
|
|
|
## How It Works
|
|
|
|
### Template Priority Order
|
|
|
|
When loading a template by name, the system checks in this order:
|
|
|
|
1. **Embedded templates** in the current project (highest priority)
|
|
2. **User templates** in `~/.pyphotoalbum/templates/`
|
|
3. **Built-in templates** in `pyPhotoAlbum/templates/`
|
|
|
|
### Automatic Embedding
|
|
|
|
Templates are automatically embedded in projects when:
|
|
|
|
- Applying a template to a page with `apply_template_to_page()`
|
|
- Creating a new page from a template with `create_page_from_template()`
|
|
|
|
You can disable auto-embedding by passing `auto_embed=False` to these methods.
|
|
|
|
### Template Naming
|
|
|
|
Templates are listed with prefixes indicating their source:
|
|
|
|
- `[Embedded] Template Name` - Embedded in current project
|
|
- `[Built-in] Template Name` - Built-in template
|
|
- `Template Name` - User template from filesystem
|
|
|
|
## Usage Examples
|
|
|
|
### Basic Usage
|
|
|
|
```python
|
|
from pyPhotoAlbum.project import Project, Page
|
|
from pyPhotoAlbum.template_manager import TemplateManager, Template
|
|
|
|
# Create a project
|
|
project = Project(name="My Album")
|
|
|
|
# Create template manager with project
|
|
template_manager = TemplateManager(project=project)
|
|
|
|
# Create a page from a template (auto-embeds by default)
|
|
template = template_manager.load_template("Grid_2x2")
|
|
page = template_manager.create_page_from_template(template, page_number=1)
|
|
project.add_page(page)
|
|
|
|
# The template is now embedded in the project!
|
|
print(project.embedded_templates.keys())
|
|
# Output: dict_keys(['Grid_2x2'])
|
|
```
|
|
|
|
### Manual Embedding
|
|
|
|
```python
|
|
# Manually embed a template
|
|
template = Template(name="Custom Layout")
|
|
# ... configure template ...
|
|
template_manager.embed_template(template)
|
|
```
|
|
|
|
### Saving Templates
|
|
|
|
```python
|
|
# Save to filesystem (default)
|
|
template_manager.save_template(template)
|
|
|
|
# Or embed in project instead
|
|
template_manager.save_template(template, embed_in_project=True)
|
|
```
|
|
|
|
### Listing Templates
|
|
|
|
```python
|
|
# List all available templates
|
|
templates = template_manager.list_templates()
|
|
# Returns: ['[Embedded] Custom', '[Built-in] Grid_2x2', 'MyUserTemplate', ...]
|
|
```
|
|
|
|
### Loading Templates
|
|
|
|
```python
|
|
# Load embedded template (priority)
|
|
template = template_manager.load_template("Custom")
|
|
|
|
# Load with explicit prefix
|
|
template = template_manager.load_template("[Embedded] Custom")
|
|
template = template_manager.load_template("[Built-in] Grid_2x2")
|
|
```
|
|
|
|
### Disabling Auto-Embed
|
|
|
|
```python
|
|
# Don't auto-embed when applying template
|
|
template_manager.apply_template_to_page(
|
|
template,
|
|
page,
|
|
auto_embed=False
|
|
)
|
|
|
|
# Don't auto-embed when creating page
|
|
page = template_manager.create_page_from_template(
|
|
template,
|
|
page_number=1,
|
|
auto_embed=False
|
|
)
|
|
```
|
|
|
|
## Project Serialization
|
|
|
|
Embedded templates are automatically serialized when saving projects:
|
|
|
|
```python
|
|
# Save project to ZIP file
|
|
from pyPhotoAlbum.project_serializer import save_to_zip
|
|
|
|
save_to_zip(project, "myalbum.ppz")
|
|
# Embedded templates are included in the .ppz file
|
|
```
|
|
|
|
When loading:
|
|
|
|
```python
|
|
from pyPhotoAlbum.project_serializer import load_from_zip
|
|
|
|
project, error = load_from_zip("myalbum.ppz")
|
|
# Embedded templates are automatically restored
|
|
|
|
# Create template manager to access them
|
|
template_manager = TemplateManager(project=project)
|
|
templates = template_manager.list_templates()
|
|
```
|
|
|
|
## Data Structure
|
|
|
|
Embedded templates are stored in the project's `embedded_templates` dictionary:
|
|
|
|
```python
|
|
project.embedded_templates = {
|
|
"Template Name": {
|
|
"name": "Template Name",
|
|
"description": "Template description",
|
|
"page_size_mm": [210, 297],
|
|
"elements": [
|
|
{
|
|
"type": "placeholder",
|
|
"position": [10, 10],
|
|
"size": [100, 100],
|
|
# ... more element data
|
|
},
|
|
# ... more elements
|
|
]
|
|
},
|
|
# ... more templates
|
|
}
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### TemplateManager
|
|
|
|
#### Constructor
|
|
```python
|
|
TemplateManager(project=None)
|
|
```
|
|
Create a template manager. Pass a `Project` instance to enable embedded template support.
|
|
|
|
#### Methods
|
|
|
|
**`embed_template(template: Template)`**
|
|
Manually embed a template in the project.
|
|
|
|
**`load_template(name: str) -> Template`**
|
|
Load a template by name. Checks embedded templates first, then filesystem.
|
|
|
|
**`list_templates() -> List[str]`**
|
|
List all available templates with source prefixes.
|
|
|
|
**`save_template(template: Template, embed_in_project: bool = False)`**
|
|
Save template to filesystem or embed in project.
|
|
|
|
**`delete_template(name: str)`**
|
|
Delete a template (works with embedded and user templates).
|
|
|
|
**`apply_template_to_page(template, page, mode="replace", scale_mode="proportional", margin_percent=2.5, auto_embed=True)`**
|
|
Apply template to a page. Auto-embeds by default.
|
|
|
|
**`create_page_from_template(template, page_number=1, target_size_mm=None, scale_mode="proportional", auto_embed=True) -> Page`**
|
|
Create a new page from template. Auto-embeds by default.
|
|
|
|
### Project
|
|
|
|
#### Attributes
|
|
|
|
**`embedded_templates: Dict[str, Dict[str, Any]]`**
|
|
Dictionary storing embedded template definitions.
|
|
|
|
## Migration Guide
|
|
|
|
### Existing Projects
|
|
|
|
Existing projects without embedded templates will continue to work normally. Templates will be auto-embedded when:
|
|
|
|
1. You apply a template to a page
|
|
2. You create a new page from a template
|
|
3. You manually embed a template
|
|
|
|
### Sharing Projects
|
|
|
|
When sharing projects:
|
|
|
|
1. Templates are automatically embedded when used
|
|
2. Save the project to .ppz format
|
|
3. Share the .ppz file
|
|
4. Recipients can open the project and all templates are available
|
|
|
|
No manual steps required!
|
|
|
|
## Best Practices
|
|
|
|
1. **Let auto-embed work**: The default behavior of auto-embedding templates ensures portability
|
|
2. **Save projects after using templates**: Embedded templates are saved with the project
|
|
3. **Use descriptive template names**: This helps identify templates in the list
|
|
4. **Test on different machines**: Verify templates work when opening projects elsewhere
|
|
|
|
## Troubleshooting
|
|
|
|
**Q: Why isn't my template showing as embedded?**
|
|
A: Ensure you're creating the TemplateManager with the project:
|
|
```python
|
|
template_manager = TemplateManager(project=project)
|
|
```
|
|
|
|
**Q: Can I convert filesystem templates to embedded?**
|
|
A: Yes, just load and embed them:
|
|
```python
|
|
template = template_manager.load_template("MyTemplate")
|
|
template_manager.embed_template(template)
|
|
```
|
|
|
|
**Q: What happens if I have templates with the same name?**
|
|
A: Embedded templates take priority over filesystem templates with the same name.
|
|
|
|
**Q: Can I remove embedded templates?**
|
|
A: Yes, use:
|
|
```python
|
|
template_manager.delete_template("[Embedded] Template Name")
|
|
```
|
|
|
|
## Implementation Details
|
|
|
|
- Templates are stored as JSON in the project's `embedded_templates` dictionary
|
|
- Serialization includes embedded templates in the project.json within .ppz files
|
|
- Template manager checks embedded templates first when loading
|
|
- Auto-embed only happens if the template isn't already embedded
|
|
- All template operations preserve element properties (position, size, rotation, etc.)
|