Advanced Usage¶
This chapter covers advanced features and best practices.
Built-in Template System¶
LatticeSVG provides 17 predefined style templates:
from latticesvg import templates
page = GridContainer(style=templates.REPORT_PAGE)
# Override specific properties
page = GridContainer(style={**templates.REPORT_PAGE, "width": "1200px"})
Layout Templates¶
| Template | Purpose |
|---|---|
REPORT_PAGE |
800px single-column page |
TWO_COLUMN |
Two equal columns |
THREE_COLUMN |
Three equal columns |
SIDEBAR_LAYOUT |
240px sidebar + flexible main |
CHART_CONTAINER |
2×2 chart grid |
Typography Templates¶
HEADER, FOOTER, TITLE, SUBTITLE, H1–H3, PARAGRAPH, CAPTION, CODE
Visual Templates¶
CARD, HIGHLIGHT_BOX
Table API¶
build_table() provides a convenient way to build tables:
from latticesvg.templates import build_table
from latticesvg import Renderer
table = build_table(
headers=["Name", "Type", "Default"],
rows=[
["width", "length", "auto"],
["padding", "length", "0px"],
["color", "color", "#000000"],
],
col_widths=["150px", "100px", "1fr"],
stripe_color="#f8f9fa",
)
Renderer().render(table, "table.svg")
Custom Table Styles¶
table = build_table(
headers=["Product", "Price", "Stock"],
rows=[["Widget A", "$9.99", "142"]],
header_style={"background-color": "#2c3e50", "color": "#ffffff"},
cell_style={"font-size": "13px", "padding": "10px 16px"},
)
PNG Output¶
For print quality, use scale=3.0 or higher.
Font Embedding¶
Subset and embed used fonts for portable SVG output:
renderer = Renderer()
renderer.render(page, "portable.svg", embed_fonts=True)
svg_string = renderer.render_to_string(page, embed_fonts=True)
Font Subsetting
Only glyphs actually used in the document are embedded (WOFF2 format),
keeping file sizes reasonable. Requires fonttools.
Rendering Without Files¶
drawing = renderer.render_to_drawing(page) # drawsvg.Drawing object
svg_string = renderer.render_to_string(page) # SVG string for HTML embedding
Layout Inspection¶
After layout, inspect each node's position and size:
page.layout(available_width=800)
print(f"Page size: {page.border_box.width} × {page.border_box.height}")
for i, child in enumerate(page.children):
bb = child.border_box
print(f"Child {i}: pos=({bb.x}, {bb.y}), size={bb.width}×{bb.height}")
min/max Sizing¶
TextNode("Adaptive width", style={
"min-width": "100px", "max-width": "400px", "min-height": "50px",
})
Best Practices¶
Style Reuse¶
card_style = {
"padding": "16px", "background-color": "#fff",
"border": "1px solid #e0e0e0", "border-radius": "8px",
}
grid.add(TextNode("Card 1", style={**card_style, "color": "#333"}))
grid.add(TextNode("Card 2", style={**card_style, "color": "#666"}))
Nested Layouts¶
Build complex pages through nested GridContainer:
page = GridContainer(style=templates.REPORT_PAGE)
header = GridContainer(style={
"grid-template-columns": ["auto", "1fr"], "gap": "16px", "align-items": "center",
})
header.add(ImageNode("logo.png", style={"width": "48px", "height": "48px"}))
header.add(TextNode("Company Name", style=templates.H1))
page.add(header)
Performance Tips¶
- Avoid deep nesting — 3-4 levels suffice for most layouts
- Reuse Renderer instances — Same
Renderer()for multiple renders - Use font embedding judiciously — Only enable
embed_fonts=Truewhen needed - Specify explicit widths — Set
widthon root containers to avoid defaults