Skip to main content

A declarative, type-safe ,Python-Native template Rendering Framework and Meta-framework for Django.

Project description

Probo UI (PUI) v1.1.0 Documentation

MUI allows you to build type-safe, server-side rendered HTML components in Python with built-in state management and JIT CSS generation.

1. Basic HTML Generation (Functional API)

The simplest way to use MUI is through its functional tags. This replaces writing raw HTML strings.

Goal: Create the "Logo Section" from your example.

from mui import section, div, img, h2, span

def logo_component():
    return div(
        img(src="./user/Images/logo.jpg", alt="logo", width="80px"),
        h2(span("CLUB"), "BAC"),
        Class="log_logo"
    )

# Render to string
print(logo_component().render())


Output:

<div class="log_logo"><img src="./user/Images/logo.jpg" alt="logo" width="80px" /><h2><span>CLUB</span>BAC</h2></div>

2. The Component Class (Static)

For reusable UI parts, use the Component class. This allows you to manage templates and CSS boundaries.

Goal: Create the "Sign Up Form" container.

from mui import Component, div, form, h2, Input, button, p, a

# 1. Define the internal structure (Template)
# We use Python functions to build the structure dynamically
def signup_template():
    return form(
        h2("Sign Up"),
        # Name Fields
        div(
            Input(type="text", placeholder="First Name", required=True),
            Input(type="text", placeholder="Last Name", required=True),
            Class="input-box1"
        ),
        # Submit
        button("Sign Up", type="submit", Class="btn", onclick="login()")
    )

# 2. Create the Component
# Passing the rendered string as the 'template'
signup_comp = Component(
    name="SignUpCard", 
    template=signup_template()
)

# 3. Add Root Styling (Optional)
signup_comp.set_root_element("div", Class="sign")

# 4. Render
html = signup_comp.render()

3. Adding State (Dynamic Components)

MUI Components become powerful when you add State. This allows you to inject data dynamically without string formatting hacks.

Goal: Make the "Welcome" header dynamic.

Step 1: Define Element State

We use ElementState to create "Smart Placeholders" (<$...>...</$>) in our template.

from mui import Component, ComponentState, ElementState, StateProps, section, h1, span

# 1. Define Logic Elements
# "Look for 'club_name' in static data (s_state)"
es_club_name = ElementState(
    'span', 
    s_state='club_name', 
    Class='highlight',
)

# "Look for 'welcome_msg' in dynamic data (d_state)"
# Strict Mode: If missing, don't render this H1 at all.
es_message = ElementState(
    element='h1', 
    d_state='welcome_msg', 
    strict_dynamic=True
)
# "Look for 'hello_1235' in dynamic data (d_state)"
# the hirarchy : d_state > s_state so in normal use if no d_stae found but s_state found the element will use the s_state value.
# Strict Mode: If missing, don't render this H1 at all.
es_message_both = ElementState(
    'h1', 
    s_state='welcome_879',
    d_state='hello_1235', 
    strict_dynamic=True
)

Step 2: Create Component State

The ComponentState acts as the "Brain" holding the data.

# 2. Define Data
state = ComponentState(
    # Static Data (Defaults)
    s_data={'club_name': 'The Biologists in Action Club'},
    
    # Dynamic Data (From Database/View)
    d_data={'welcome_msg': 'Jack the admin says: Welcome !!'},
    
    # Register elements so the State knows about them
    es_club_name, es_message, es_message_both,
)

Step 3: Wire it Together

We construct the template using the elements' placeholders.

# 3. Build Template using Placeholders
# <$ ... $> is automatically inserted by .placeholder
template_str = section(
    es_message.placeholder,  # <h1>Welcome to </h1>
    es_message_both.placeholder,  # <h1>Welcome to </h1>
    es_club_name.placeholder, # <span class="highlight">The Biologists...</span>
    Class="page"
)

# 4. Initialize Component
page_component = Component(
    name="HomePage",
    template=template_str,
    state=state
)

# 5. Render
# The Component automatically resolves data -> elements -> HTML
html = page_component.render()
print(html):
<section class="page"><span class="highlight">The Biologists in Action Club</span><h1>Jack the admin says: Welcome !!</h1></section>

4. Styling (JIT CSS)

MUI allows you to attach CSS rules directly to components. These are only rendered if the elements exist.

from mui import CssRule, CssSelector

# Define Rules
btn_style = {CssSelector().cls('btn'):CssRule(background_color='blue', color='white')}
input_style = {CssSelector().cls('input-box'):CssRule(padding='40px', margin_bottom='10px')}

# Load into Component , this a binding css to component
signup_comp.load_css_rules(**{**btn_style, **input_style})
# setting root elemnt
signup_comp.set_root_element('main',Id="main")
# Changing Skins (Theming)
# You can swap styles entirely at runtime
signup_comp.change_skin(
    root_attr='class',
    root_attr_value='root_css',
    root_css={'background': '#f0f0f0', 'padding': '20px'} # Applied to root div
)

5. Full Architecture Example (The "shortcut")

For the best developer experience, use the shortcut to wire everything in one go.

from mui.shortcuts import (component, ComponentConfig, StateConfig, StyleConfig,ElementStateConfig)
from mui import (ElementState, div, form,)

def build_signup_page():
    # 1. Logic
    title_state = ElementStateConfig(tag='h2', s_state='form_title')
    
    
    state_config = StateConfig(
        s_data={'form_title': 'Join the Club'},
        elements_state_config=[title_state,]
    )
    # 2. Style
    style_config = StyleConfig(
        css = {
            '.sign': {'background': '#fff', 'padding': '2px'},
            'input': {'width': '100%', 'padding': '10px'},#since no input element this is skipped
        }
    )
    config = ComponentConfig(
        name="SignUpPage",
        template=div(title_state.config_id,form('some form'),Class="sign"),
        # Configuration
        state_config=state_config,
        style_config=style_config,
    )
    # 3. Component
    return component(config)
print(build_signup_page())
('<div class="sign"><form>some form</form></div>', '.sign { background:#fff; padding:2px; }')

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

probo_ui-1.1.1.tar.gz (480.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

probo_ui-1.1.1-py3-none-any.whl (118.5 kB view details)

Uploaded Python 3

File details

Details for the file probo_ui-1.1.1.tar.gz.

File metadata

  • Download URL: probo_ui-1.1.1.tar.gz
  • Upload date:
  • Size: 480.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for probo_ui-1.1.1.tar.gz
Algorithm Hash digest
SHA256 a38544ad7c7165aff1336ad2333ceac495f8030292488b36ff79b055a7089136
MD5 aa7c2b878462fcd9ce3174f6970d3ceb
BLAKE2b-256 601c4c2f3f19e2db8f559aba4d99c7c3cfdb15ec11199c5fa8f5ae8441709fce

See more details on using hashes here.

File details

Details for the file probo_ui-1.1.1-py3-none-any.whl.

File metadata

  • Download URL: probo_ui-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 118.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for probo_ui-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4a1cd40384f734b136cedf8d3162939350fb23b47d663fc3b27fd4d97978aecd
MD5 0dd033e884d8086aa0f59dbd1d123d9d
BLAKE2b-256 3ecea70dd1a0ae68f049948d70724cdc8f53a67a6d7f76fd63ae4dcd14642420

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page