CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-dominate

A Python library for creating and manipulating HTML documents using an elegant DOM API

Pending
Overview
Eval results
Files

dom-manipulation.mddocs/

DOM Manipulation

Core DOM tree manipulation with element creation, attribute management, content addition/removal, searching, and rendering with customizable formatting. Includes context manager support and decorator functionality.

Capabilities

Base DOM Tag Class

Foundation class providing core DOM manipulation functionality for all elements.

class dom_tag:
    def __init__(self, *args, **kwargs):
        """
        Create a new DOM element.
        
        Parameters:
        - *args: Child elements, text content, or iterables
        - **kwargs: Element attributes and special rendering options
        
        Special kwargs:
        - __inline (bool): Render children inline
        - __pretty (bool): Enable pretty printing
        """
    
    # Class attributes
    is_single: bool = False   # Self-closing tag (e.g., <br/>, <img/>)
    is_pretty: bool = True    # Pretty print content by default
    is_inline: bool = False   # Inline rendering
    
    # Instance attributes
    attributes: dict          # Element attributes
    children: list           # Child elements and text
    parent: dom_tag | None   # Parent element

Element Creation and Content Management

Add, remove, and manipulate element content and children.

def add(self, *args):
    """
    Add child elements or content to this element.
    
    Parameters:
    - *args: Elements, text, numbers, dicts (attributes), or iterables
    
    Returns:
    - Single element if one arg, tuple of elements if multiple args
    """

def remove(self, obj):
    """
    Remove a child element.
    
    Parameters:
    - obj: Child element to remove
    """

def clear(self):
    """
    Remove all child elements and reset parent references.
    """

def add_raw_string(self, s):
    """
    Add raw string content without escaping.
    
    Parameters:
    - s (str): Raw string to add
    """

Usage Examples

from dominate.tags import div, p, a, ul, li
from dominate.util import text

# Basic content addition
container = div()
container.add(p('First paragraph'))
container.add(p('Second paragraph'))

# Multiple elements at once
heading, content = container.add(h1('Title'), div(cls='content'))

# Different content types
element = div()
element.add('Plain text')              # String
element.add(42)                        # Number (converted to string)
element.add(p('Paragraph'))            # Element
element.add({'class': 'my-class'})     # Attributes dict
element.add([li('Item 1'), li('Item 2')])  # Iterable

# Using += operator
nav = ul()
nav += li(a('Home', href='/'))
nav += li(a('About', href='/about'))

# Clear content
container.clear()  # Removes all children

# Raw string (no escaping)
div_element = div()
div_element.add_raw_string('<em>This will not be escaped</em>')

Attribute Management

Set, get, and delete element attributes with dictionary-like interface.

def set_attribute(self, key, value):
    """
    Set an element attribute.
    
    Parameters:
    - key (str|int): Attribute name or child index
    - value: Attribute value or child element
    """

def delete_attribute(self, key):
    """
    Delete an attribute or child element.
    
    Parameters:
    - key (str|int): Attribute name or child index
    """

def __getitem__(self, key):
    """
    Get attribute value or child element.
    
    Parameters:
    - key (str|int): Attribute name or child index
    
    Returns:
    - Attribute value or child element
    """

def __setitem__(self, key, value):
    """Dictionary-style attribute/child setting."""

def __delitem__(self, key):
    """Dictionary-style attribute/child deletion."""

Usage Examples

# Attribute management
element = div()

# Set attributes
element.set_attribute('class', 'container')
element['id'] = 'main-div'
element.data_value = '123'  # Using attribute access

# Get attributes
class_name = element['class']
element_id = element.id

# Delete attributes
del element['class']
element.delete_attribute('id')

# Child element access
list_element = ul(li('Item 1'), li('Item 2'))
first_item = list_element[0]        # Get first child
list_element[1] = li('New Item 2')  # Replace second child
del list_element[0]                 # Remove first child

Element Search and Navigation

Find elements within the DOM tree using various criteria.

def get(self, tag=None, **kwargs):
    """
    Recursively search for child elements.
    
    Parameters:
    - tag (str|class|None): Tag type to search for
    - **kwargs: Attribute filters
    
    Returns:
    - list: Matching elements
    """

@property
def parent(self):
    """Get the parent element."""

def __contains__(self, item):
    """
    Check if element contains a specific tag type.
    
    Parameters:
    - item (str|class): Tag type to check for
    
    Returns:
    - bool: True if found in children tree
    """

Usage Examples

# Search examples
document = div(
    div(p('Content 1'), id='section1', cls='content'),
    div(p('Content 2'), id='section2', cls='content'),
    p('Footer text', cls='footer')
)

# Find by tag type
paragraphs = document.get('p')           # All <p> elements
divs = document.get(div)                 # All div elements

# Find by attributes
content_divs = document.get(cls='content')        # class="content"
section1 = document.get(id='section1')           # id="section1"
footer_p = document.get('p', cls='footer')       # <p> with class="footer"

# Check containment
has_paragraphs = 'p' in document        # True
has_tables = 'table' in document        # False

# Navigation
first_div = document[0]                 # First child
parent_element = first_div.parent       # Back to document

Context Manager Support

Use elements as context managers with Python's with statement for clean, hierarchical markup creation.

def __enter__(self):
    """
    Enter context manager mode.
    
    Returns:
    - self: The element instance
    """

def __exit__(self, type, value, traceback):
    """
    Exit context manager, adding any unassigned elements to this element.
    
    Parameters:
    - type, value, traceback: Exception information (if any)
    """

Usage Examples

# Context manager usage
container = div(cls='main-container')

with container:
    h1('Page Title')
    p('This paragraph will be added to the container.')
    
    with ul(cls='nav-menu'):
        li(a('Home', href='/'))
        li(a('About', href='/about'))
        li(a('Contact', href='/contact'))

# Nested contexts
page = div()
with page:
    with header():
        h1('Site Title')
        nav(
            a('Link 1', href='/1'),
            a('Link 2', href='/2')
        )
    
    with main():
        article(
            h2('Article Title'),
            p('Article content here.')
        )
    
    footer('© 2023 Site Name')

Decorator Support

Use elements as decorators for functions to create reusable widgets and components.

def __new__(cls, *args, **kwargs):
    """
    Handle decorator usage when element class is used with single callable argument.
    
    Returns:
    - Decorated function or new element instance
    """

def __call__(self, func):
    """
    Use element instance as decorator.
    
    Parameters:
    - func: Function to decorate
    
    Returns:
    - Decorated function that returns element with function result
    """

Usage Examples

# Class decorator (creates new instance each call)
@div
def create_card(title, content):
    h3(title)
    p(content)

card1 = create_card('Card 1', 'Content for card 1')
card2 = create_card('Card 2', 'Content for card 2')

# Instance decorator (copies instance each call)
@div(cls='alert alert-info')
def info_message(text):
    p(text)

message1 = info_message('This is an info message')
message2 = info_message('Another info message')

# More complex widget
@div(cls='product-card')
def product_card(name, price, description):
    with div(cls='card-header'):
        h4(name)
        span(f'${price}', cls='price')
    
    with div(cls='card-body'):
        p(description)
        button('Add to Cart', cls='btn btn-primary')

product = product_card('Widget', 19.99, 'A useful widget for your needs.')

Rendering and Output

Control how elements are rendered to HTML with various formatting options.

def render(self, indent='  ', pretty=True, xhtml=False):
    """
    Render element to HTML string.
    
    Parameters:
    - indent (str): Indentation string for pretty printing
    - pretty (bool): Enable pretty printing with indentation
    - xhtml (bool): Use XHTML-style self-closing tags
    
    Returns:
    - str: Rendered HTML
    """

def _render(self, sb, indent_level, indent_str, pretty, xhtml):
    """
    Internal rendering method.
    
    Parameters:
    - sb (list): String buffer for output
    - indent_level (int): Current indentation level
    - indent_str (str): Indentation string
    - pretty (bool): Pretty printing enabled
    - xhtml (bool): XHTML mode
    
    Returns:
    - list: Updated string buffer
    """

def __str__(self):
    """String representation using render()."""

def __unicode__(self):
    """Unicode representation using render()."""

Usage Examples

# Rendering options
element = div(
    h1('Title'),
    p('Content here')
)

# Default pretty printing
html = element.render()
# <div>
#   <h1>Title</h1>
#   <p>Content here</p>
# </div>

# Compact rendering
compact = element.render(pretty=False)
# <div><h1>Title</h1><p>Content here</p></div>

# Custom indentation
tabbed = element.render(indent='\t')
# <div>
# 	<h1>Title</h1>
# 	<p>Content here</p>
# </div>

# XHTML mode
xhtml = element.render(xhtml=True)
# Self-closing tags get /> instead of >

# String conversion
html_string = str(element)  # Same as element.render()

Collection Interfaces

Elements support standard Python collection operations.

def __len__(self):
    """
    Get number of child elements.
    
    Returns:
    - int: Number of children
    """

def __iter__(self):
    """
    Iterate over child elements.
    
    Returns:
    - iterator: Child element iterator
    """

def __bool__(self):
    """
    Boolean evaluation (always True for elements).
    
    Returns:
    - bool: Always True
    """

Usage Examples

# Collection operations
menu = ul(
    li('Item 1'),
    li('Item 2'),
    li('Item 3')
)

# Length
num_items = len(menu)  # 3

# Iteration
for item in menu:
    print(item)  # Prints each <li> element

# Boolean evaluation
if menu:  # Always True for elements
    print('Menu exists')

# List-like operations
first_item = menu[0]
last_item = menu[-1]
menu.append(li('Item 4'))  # Error: use add() instead

Attribute Name Conversion

Automatic conversion of Python attribute names to HTML-compatible names.

@staticmethod
def clean_attribute(attribute):
    """
    Convert Python attribute names to HTML attribute names.
    
    Parameters:
    - attribute (str): Python attribute name
    
    Returns:
    - str: HTML-compatible attribute name
    """

@classmethod
def clean_pair(cls, attribute, value):
    """
    Clean attribute name and handle boolean values.
    
    Parameters:
    - attribute (str): Attribute name
    - value: Attribute value
    
    Returns:
    - tuple: (cleaned_attribute, processed_value)
    """

Usage Examples

# Attribute name conversions
element = div(
    cls='my-class',           # 'cls' -> 'class'
    class_name='other',       # 'class_name' -> 'class'
    fr='input-id',           # 'fr' -> 'for'
    html_for='input-id',     # 'html_for' -> 'for'
    data_value='123',        # 'data_value' -> 'data-value'
    aria_label='Description', # 'aria_label' -> 'aria-label'
    _private='hidden',       # '_private' -> 'private'
    http_equiv='refresh'     # 'http_equiv' -> 'http-equiv'
)

# Boolean attribute handling
checkbox = input_(
    type='checkbox',
    checked=True,    # becomes checked="checked"
    disabled=False   # omitted from output
)

DOM Level 1 Core API

W3C DOM Level 1 Core specification compliance for standard DOM operations.

@property
def parentNode(self):
    """
    DOM API: Get the parent element.
    
    Returns:
    - dom_tag|None: Parent element or None if root
    """

def getElementById(self, id):
    """
    DOM API: Get element with specified ID.
    
    Parameters:
    - id (str): Element ID to search for
    
    Returns:
    - dom_tag|None: Element with matching ID or None
    
    Raises:
    - ValueError: If multiple elements have the same ID
    """

def getElementsByTagName(self, name):
    """
    DOM API: Get all elements with specified tag name.
    
    Parameters:
    - name (str): Tag name to search for
    
    Returns:
    - list: All matching elements
    """

def appendChild(self, obj):
    """
    DOM API: Add child element to the end of children list.
    
    Parameters:
    - obj: Element to add as child
    
    Returns:
    - self: The parent element (for chaining)
    """

Usage Examples

# DOM Level 1 Core API usage
document = div(
    div(p('Section 1'), id='section1'),
    div(p('Section 2'), id='section2'),
    p('Footer', id='footer')
)

# Get element by ID
section1 = document.getElementById('section1')
print(section1)  # <div id="section1">...</div>

# Handle multiple/missing IDs
try:
    missing = document.getElementById('nonexistent')  # Returns None
    print(missing)
except ValueError as e:
    print(f'Error: {e}')  # If multiple elements have same ID

# Get elements by tag name
all_paragraphs = document.getElementsByTagName('p')
print(len(all_paragraphs))  # 2

all_divs = document.getElementsByTagName('div')
print(len(all_divs))  # 2

# Append child (DOM-style)
new_section = div(p('New section'), id='section3')
document.appendChild(new_section)

# Parent navigation
child = document.getElementById('section1')
parent = child.parentNode  # Returns the document div

Context Management Functions

Global functions for working with context managers and current element state.

def get_current(default=None):
    """
    Get the current element in context manager scope.
    
    Parameters:
    - default: Value to return if no current context
    
    Returns:
    - dom_tag|default: Current context element or default
    
    Raises:
    - ValueError: If no current context and no default provided
    """

def attr(*args, **kwargs):
    """
    Set attributes on the current context element.
    
    Parameters:
    - *args: Dictionaries of attributes
    - **kwargs: Attribute key-value pairs
    """

Usage Examples

# Context functions
with div() as container:
    p('Content here')
    
    # Get current context
    current = get_current()  # Returns the div
    
    # Set attributes on current context
    attr(id='main-container', cls='wrapper')
    attr({'data-value': '123'})

# Outside context
try:
    current = get_current()
except ValueError:
    print('No current context')

# With default
current = get_current(default=None)  # Returns None if no context

Install with Tessl CLI

npx tessl i tessl/pypi-dominate

docs

document.md

dom-manipulation.md

html-elements.md

index.md

svg.md

utilities.md

tile.json