LayoutML - a library for creating HTML pages using Python
Project description
LayoutML (Layout Markup Library) is a library that allows you to describe the structure of web pages directly in code, turning Python into a markup language for web interfaces.
Key Features
- Create HTML elements using Python classes
- Define CSS styles programmatically
- Component-based approach (reusable layout blocks)
- Clean and declarative syntax
- Generate pure HTML/CSS without unnecessary code
- Easy integration with FastAPI, Flask, Django
- Lightweight with no external dependencies
Who is it for
- Python developers who don’t want to write HTML manually
- Backend developers (FastAPI / Django / Flask)
- Educational projects
- Generating HTML reports and interfaces
- Building custom web frameworks on top of LayoutML
Contents
Core Classes
- CSSBase - Base class for working with CSS styles
- CSSInline - Class for inline styles
- CSSSelectors - Class for managing CSS selectors
Base Elements
- BaseElement - Base class for all HTML elements
- HTMLElement - Class for handling HTML attributes
Semantic Elements
- Header - Semantic
<header>element - Main - Semantic
<main>element - Footer - Semantic
<footer>element - Nav - Semantic
<nav>element - Section - Semantic
<section>element - Article - Semantic
<article>element - Aside - Semantic
<aside>element
Text Elements
- Paragraph -
<p>element - Span - Inline container
<span> - Anchor - Link
<a> - Heading - Headings
<h1>-<h6> - ListElement - Base class for lists
- UnorderedList -
<ul> - OrderedList -
<ol>
Media Elements
- Image -
<img>
Form Elements
- Form - Base form class
- FormElement -
<input> - Input - Specialized input
- Label -
<label> - Button -
<button> - Select -
<select> - Textarea -
<textarea>
Layout
- Layout - Base layout (Flexbox)
- HorizontalLayout - Horizontal layout
- VerticalLayout - Vertical layout
Document Structure
Routing
- Router - URL routing class
Application
- LayoutML - Main application class
Quick Start
Installation
pip install layoutml
Example Usage
This section provides examples of building web applications using LayoutML. You will learn how to create pages, add elements, and run the server.
Basic Run
The simplest way to run a LayoutML application:
from layoutml import LayoutML, Page
from layoutml.elements import Header, Paragraph, Button
class BasePage(Page):
def __init__(self, doctype="html", title="LayoutML", lang="en", object_name=None, **kwargs):
super().__init__(doctype, title, lang, object_name, **kwargs)
self.head.set_icon("ico/logo.ico")
# Create the application
app = LayoutML()
# Define a route
@app.route("/")
def home():
page = BasePage(title="Home")
# Create elements
header = Header()
header.get_html(content="<h1>Welcome!</h1>")
paragraph = Paragraph(text="This is an example of using LayoutML")
button = Button(text="Click me", onclick="alert('Hello!')")
# Add elements to the page
page.body.add_element(header)
page.body.add_element(paragraph)
page.body.add_element(button)
return page
# Run the application
if __name__ == "__main__":
app.start(host="localhost", port=3700)
Running via Uvicorn from the Command Line
You can run the application using Uvicorn from the terminal:
pip install uvicorn
uvicorn main:app --host localhost --port 3700 --reload
Where main is the name of your Python file, and app is the name of your LayoutML application instance.
Running via Uvicorn from Python Code
You can also run Uvicorn directly from a Python script:
if __name__ == "__main__":
uvicorn.run(app, host="localhost", port=3700)
Creating Multiple Routes
Example of an application with multiple pages:
from layoutml import LayoutML, Page
from layoutml.elements import Header, Paragraph, Button, Anchor
app = LayoutML()
@app.route("/")
def home():
page = Page(title="Home")
header = Header()
header.get_html(content="<h1>Home Page</h1>")
paragraph = Paragraph(text="Welcome to our website!")
link = Anchor(href="/about", text="About Us")
page.body.add_element(header)
page.body.add_element(paragraph)
page.body.add_element(link)
return page
@app.route("/about")
def about():
page = Page(title="About")
header = Header()
header.get_html(content="<h1>About Our Company</h1>")
paragraph = Paragraph(text="We build web applications using LayoutML")
back_link = Anchor(href="/", text="Back to Home")
page.body.add_element(header)
page.body.add_element(paragraph)
page.body.add_element(back_link)
return page
if __name__ == "__main__":
app.start()
Using Route Parameters
You can create dynamic pages with parameters in the URL:
from layoutml import LayoutML, Page
from layoutml.elements import Header, Paragraph
app = LayoutML()
@app.route("/user/<username>")
def user_profile(username: str):
page = Page(title=f"Profile {username}")
header = Header()
header.get_html(content=f"<h1>User Profile: {username}</h1>")
paragraph = Paragraph(text=f"Welcome, {username}!")
page.body.add_element(header)
page.body.add_element(paragraph)
return page
if __name__ == "__main__":
app.start()
Adding CSS Styles
Example of a page with custom styles:
from layoutml import LayoutML, Page
from layoutml.elements import Header, Paragraph, Button
app = LayoutML()
@app.route("/")
def styled_page():
page = Page(title="Styled Page")
# Create an element with CSS classes
header = Header(class_="main-header")
header.get_html(content="<h1>Styled Page</h1>")
paragraph = Paragraph(
text="This text is styled using CSS",
class_="highlight-text"
)
button = Button(
text="Styled Button",
class_="custom-button",
style="padding: 10px 20px; background: #007bff; color: white; border: none; border-radius: 5px;"
)
# Add CSS styles via the head object
page.head.selectors_styles.add_selector(".main-header")\
.set_background_color("#f8f9fa")\
.set_padding("20px")\
.set_text_align("center")
page.head.selectors_styles.add_selector(".highlight-text")\
.set_color("#007bff")\
.set_font_size("18px")\
.set_font_weight("bold")
page.head.selectors_styles.add_selector(".custom-button:hover")\
.set_background_color("#0056b3")\
.set_transform("scale(1.05)")
page.body.add_element(header)
page.body.add_element(paragraph)
page.body.add_element(button)
return page
if __name__ == "__main__":
app.start()
Using Layouts
Creating a page using horizontal and vertical layouts:
from layoutml import LayoutML, Page
from layoutml.elements import Header, Paragraph, Button
from layoutml.layout import HorizontalLayout, VerticalLayout
app = LayoutML()
@app.route("/")
def layout_example():
page = Page(title="Layout Example")
# Vertical layout for the entire page
main_layout = VerticalLayout(object_name="mainLayout")
main_layout.object_styles.set_gap("20px").set_padding("20px")
# Horizontal layout for navigation
nav_layout = HorizontalLayout(object_name="navLayout")
nav_layout.object_styles.set_justify_content("space-between")
nav_layout.add_element(Button(text="Home"))
nav_layout.add_element(Button(text="About"))
nav_layout.add_element(Button(text="Contacts"))
# Horizontal layout for cards
cards_layout = HorizontalLayout(object_name="cardsLayout")
cards_layout.object_styles.set_gap("20px").set_justify_content("center")
for i in range(3):
card = VerticalLayout(object_name=f"card{i}")
card.object_styles.set_border("1px solid #ddd")\
.set_padding("15px")\
.set_border_radius("8px")\
.set_width("200px")
card.add_element(Paragraph(text=f"Card {i+1}"))
card.add_element(Button(text="Learn More"))
cards_layout.add_element(card)
main_layout.add_elements(nav_layout, cards_layout)
page.body.add_element(main_layout)
return page
if __name__ == "__main__":
app.start()
Handling Forms
Example of creating a page with a form and handling data:
from layoutml import LayoutML, Page
from layoutml.elements import Input, Button, Label, Paragraph
app = LayoutML()
@app.route("/contact", methods=["GET", "POST"])
def contact_page():
page = Page(title="Contacts")
page.body.add_element(Paragraph(text="Get in touch with us"))
# Create a form
form = BaseElement(tag="form", method="post", action="/submit")
# Name field
form.add_element(Label(for_id="name", text="Name:"))
form.add_element(Input(id="name", name="name", required=True))
# Email field
form.add_element(Label(for_id="email", text="Email:"))
form.add_element(Input(type="email", id="email", name="email", required=True))
# Submit button
form.add_element(Button(text="Submit", type="submit"))
page.body.add_element(form)
return page
if __name__ == "__main__":
app.start()
Development Tips
-
Development mode: Use the
--reloadflag when running via Uvicorn for automatic server reload on code changes. -
Debugging: You can print route information using the
print_routes()method:
app.print_routes()
- Code organization: For larger applications, it is recommended to split routes into modules:
# routes.py
from layoutml import LayoutML
app = LayoutML()
# Import routes from other modules
from .home_routes import home_router
from .api_routes import api_router
app.include_router(home_router)
app.include_router(api_router, prefix="/api")
- Asynchronous handlers: LayoutML supports async functions for route handling:
@app.route("/async-data")
async def async_data():
data = await fetch_data_from_db()
page = Page(title="Data")
page.body.add_element(Paragraph(text=str(data)))
return page
))())()()() After запуск the server will be available at http://localhost:3700
Project Status
LayoutML is under active development.
📄 License
Feedback
I am always happy to receive your feedback and suggestions for improving LayoutML. Please leave your comments.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file layoutml-1.0.3.tar.gz.
File metadata
- Download URL: layoutml-1.0.3.tar.gz
- Upload date:
- Size: 39.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e5ca231082e5cba56dd5544af4a1ad7e220a6de0ed3ec63a10ed5a32f40ce6dd
|
|
| MD5 |
17bf05873ea110e64bba4850b66e7379
|
|
| BLAKE2b-256 |
84cd240bfa86a403ae1aa65ae02cdcc67956b7366e34f334d82f4ad4fbbcd417
|
File details
Details for the file layoutml-1.0.3-py3-none-any.whl.
File metadata
- Download URL: layoutml-1.0.3-py3-none-any.whl
- Upload date:
- Size: 49.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
84ae9d36ddb27d110c2cab30c1feb6df2993d3c803b09e2131f6e7275aea2449
|
|
| MD5 |
24c37bb57b9ab8f8889e1195e029462f
|
|
| BLAKE2b-256 |
f1946ae49c26f3542f1aa44f722ef8d18e4f9ad4e702b1deafba10883a9105a9
|