A library to generate HTML + JS pages, spun off from folium and based on Jinja2
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Comprehensive HTML generation system based on Jinja2 templating for creating structured web content. Provides hierarchical element organization, template-based rendering, and specialized components for building complete HTML documents and interactive visualizations.
Base element class providing template rendering, child management, and hierarchical document structure.
class Element:
def __init__(self, template=None, template_name=None):
"""
Create basic HTML element with optional template.
Parameters:
- template: Jinja2 template string for custom rendering
- template_name: filename of template from branca templates
"""
def get_name(self) -> str:
"""
Get unique string identifier for this element.
Returns:
str: unique element name (camelCase + ID)
"""
def add_child(self, child, name=None, index=None):
"""
Add child element to this element.
Parameters:
- child: Element instance to add as child
- name: optional name for the child (auto-generated if None)
- index: optional position index for insertion
Returns:
Element: self for method chaining
"""
def add_children(self, child, name=None, index=None):
"""
Add child element to this element (deprecated, use add_child instead).
Parameters:
- child: Element instance to add as child
- name: optional name for the child (auto-generated if None)
- index: optional position index for insertion
Returns:
Element: self for method chaining
"""
def add_to(self, parent, name=None, index=None):
"""
Add this element to a parent element.
Parameters:
- parent: Element instance to add this element to
- name: optional name for this element
- index: optional position index for insertion
Returns:
Element: self for method chaining
"""
def get_bounds(self) -> list:
"""
Get bounding box coordinates for this element and children.
Returns:
list: [[lat_min, lon_min], [lat_max, lon_max]] with Optional[float] values
"""
def get_root(self) -> "Element":
"""
Get root element in the element tree.
Returns:
Element: root element instance
"""
def render(self, **kwargs) -> str:
"""
Render element to HTML string using template.
Parameters:
- **kwargs: template variables for rendering
Returns:
str: rendered HTML content
"""
def save(self, outfile, close_file=True, **kwargs):
"""
Save rendered HTML to file.
Parameters:
- outfile: file path or file object
- close_file: whether to close file after writing
- **kwargs: template variables for rendering
"""
def to_dict(self, depth: int = -1, ordered: bool = True, **kwargs):
"""
Convert element tree to dictionary representation.
Parameters:
- depth: maximum depth for recursion (-1 for unlimited)
- ordered: whether to use OrderedDict
Returns:
dict | OrderedDict: dictionary representation of element tree
"""
def to_json(self, depth: int = -1, **kwargs) -> str:
"""
Convert element tree to JSON string.
Parameters:
- depth: maximum depth for recursion (-1 for unlimited)
- **kwargs: additional JSON serialization options
Returns:
str: JSON representation of element tree
"""Figure class for creating full HTML documents with separate header, body, and script sections.
class Figure:
def __init__(
self,
width: str = "100%",
height=None,
ratio: str = "60%",
title=None,
figsize=None
):
"""
Create complete HTML document structure.
Parameters:
- width: document width (percentage or pixels)
- height: document height (percentage or pixels)
- ratio: aspect ratio when height is None
- title: HTML document title
- figsize: matplotlib-style (width, height) in inches (60 DPI)
"""
# Attributes
header: Element # HTML head section
html: Element # HTML body section
script: Element # JavaScript section
def render(self, **kwargs) -> str:
"""
Render complete HTML document.
Parameters:
- **kwargs: template variables
Returns:
str: complete HTML document string
"""
def _repr_html_(self, **kwargs) -> str:
"""
Jupyter notebook display representation.
Returns:
str: HTML iframe for notebook display
"""
def add_subplot(self, x: int, y: int, n: int, margin: float = 0.05):
"""
Create matplotlib-style subplot div.
Parameters:
- x: number of rows in grid
- y: number of columns in grid
- n: cell number (1 to x*y)
- margin: spacing factor around subplot
Returns:
Div: positioned div element for subplot
"""Specialized elements for embedding HTML content with custom styling and positioning.
class Html:
def __init__(
self,
data: str,
script: bool = False,
width = "100%",
height = "100%"
):
"""
Create HTML div element with embedded content.
Parameters:
- data: HTML content string
- script: if True, data is embedded without HTML escaping
- width: div width (percentage, pixels, or tuple)
- height: div height (percentage, pixels, or tuple)
"""
def render(self, **kwargs) -> str:
"""
Render HTML div with content.
Returns:
str: HTML div element with embedded content
"""
class Div:
def __init__(
self,
width = "100%",
height = "100%",
left = "0%",
top = "0%",
position: str = "relative"
):
"""
Create positioned div container for layout.
Parameters:
- width: div width (percentage, pixels, or tuple)
- height: div height (percentage, pixels, or tuple)
- left: left position offset
- top: top position offset
- position: CSS position property value
"""
# Attributes (inherited from Figure)
header: Element # CSS styles section
html: Element # Content section
script: Element # JavaScript section
def render(self, **kwargs):
"""
Render positioned div with styles in parent Figure.
Must be added to a Figure to render properly.
"""IFrame element for embedding complete web pages with isolated JavaScript environments.
class IFrame:
def __init__(
self,
html=None,
width: str = "100%",
height=None,
ratio: str = "60%",
figsize=None
):
"""
Create iframe element with base64-encoded content.
Parameters:
- html: HTML content string or Element instance
- width: iframe width (percentage or pixels)
- height: iframe height (percentage or pixels)
- ratio: aspect ratio when height is None
- figsize: matplotlib-style (width, height) in inches
"""
def render(self, **kwargs) -> str:
"""
Render iframe with base64-encoded content.
Returns:
str: HTML iframe element with data URL
"""Elements for embedding JavaScript and CSS resources from URLs.
class Link:
def __init__(self, url: str, download: bool = False):
"""
Base class for external resource links.
Parameters:
- url: resource URL
- download: whether to download content immediately
"""
def get_code(self) -> bytes:
"""
Download and return resource content.
Returns:
bytes: downloaded content
"""
class JavascriptLink(Link):
def __init__(self, url: str, download: bool = False):
"""
JavaScript link element for embedding JS files.
Parameters:
- url: JavaScript file URL
- download: whether to download content immediately
"""
class CssLink(Link):
def __init__(self, url: str, download: bool = False):
"""
CSS link element for embedding stylesheets.
Parameters:
- url: CSS file URL
- download: whether to download content immediately
"""MacroElement base class for creating complex components with multiple HTML sections.
class MacroElement:
def __init__(self):
"""
Base class for elements using Jinja2 macro templates.
Subclasses should define _template with header, html, and script macros.
"""
def render(self, **kwargs):
"""
Process macro template and add sections to parent Figure.
Must be added to a Figure to render properly.
"""from branca.element import Figure, Html, JavascriptLink, CssLink
# Create basic HTML document
fig = Figure(width='800px', height='600px', title='My Page')
# Add CSS and JavaScript resources
fig.header.add_child(CssLink('https://cdn.example.com/styles.css'))
fig.header.add_child(JavascriptLink('https://cdn.example.com/script.js'))
# Add HTML content
content = Html('<h1>Welcome</h1><p>This is my page content.</p>', script=True)
fig.html.add_child(content)
# Add JavaScript code
fig.script.add_child(Html('console.log("Page loaded");', script=True))
# Save to file
fig.save('my_page.html')from branca.element import Figure, Div, Html
fig = Figure(width='1000px', height='600px')
# Create header div
header = Div(width='100%', height='80px', top='0%', position='absolute')
header.html.add_child(Html('<h1>Page Header</h1>', script=True))
fig.add_child(header)
# Create sidebar div
sidebar = Div(width='200px', height='520px', left='0%', top='80px', position='absolute')
sidebar.html.add_child(Html('<nav>Navigation Menu</nav>', script=True))
fig.add_child(sidebar)
# Create main content div
main_content = Div(width='800px', height='520px', left='200px', top='80px', position='absolute')
main_content.html.add_child(Html('<main>Main Content Area</main>', script=True))
fig.add_child(main_content)
fig.save('layout.html')from branca.element import Figure, Html
fig = Figure(figsize=(12, 8))
# Create 2x2 grid of subplots
for i in range(1, 5):
subplot = fig.add_subplot(2, 2, i, margin=0.05)
subplot.html.add_child(Html(f'<h3>Subplot {i}</h3>', script=True))
fig.save('subplots.html')from branca.element import Figure, IFrame, Html
# Create iframe with isolated HTML content
iframe_content = '''
<html>
<head><title>Iframe Content</title></head>
<body>
<h2>This content is isolated</h2>
<script>console.log("Iframe script");</script>
</body>
</html>
'''
fig = Figure()
iframe = IFrame(iframe_content, width='600px', height='400px')
fig.html.add_child(iframe)
fig.save('iframe_example.html')# Size parsing type for width/height parameters
TypeParseSize = int | float | str | tuple[float, str]# Jinja2 environment for branca templates
ENV: EnvironmentInstall with Tessl CLI
npx tessl i tessl/pypi-branca