tivelweb 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
tivelweb-0.1.0/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 tivalsdeveloper
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files, to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies, subject to including this notice.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
@@ -0,0 +1,81 @@
1
+ Metadata-Version: 2.4
2
+ Name: tivelweb
3
+ Version: 0.1.0
4
+ Summary: Build responsive static websites using friendly Python code.
5
+ Author: tivalsdeveloper
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/tivalsdeveloper-oss/tivelweb
8
+ Project-URL: Repository, https://github.com/tivalsdeveloper-oss/tivelweb
9
+ Project-URL: Issues, https://github.com/tivalsdeveloper-oss/tivelweb/issues
10
+ Keywords: website,static-site-generator,html,python
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Requires-Python: >=3.9
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Dynamic: license-file
18
+
19
+ # TivelWeb
20
+
21
+ TivelWeb is a lightweight Python library for building responsive static websites without writing all the HTML and CSS yourself.
22
+
23
+ ## Install locally
24
+
25
+ ```bash
26
+ cd tivelweb
27
+ python -m venv .venv
28
+ source .venv/bin/activate
29
+ pip install -e .
30
+ ```
31
+
32
+ ## Build your first website
33
+
34
+ ```python
35
+ from tivelweb import Site, hero, section
36
+
37
+ site = Site("My Website", theme_color="#6c5ce7")
38
+ home = site.page("Home", description="My first Python website")
39
+ home.add(hero("Welcome", "This website was built using Python.", "Learn more", "#about"))
40
+ home.add(section("About", "TivelWeb generates fast static HTML."))
41
+ site.build()
42
+ ```
43
+
44
+ Run the file, then preview the generated `dist` folder:
45
+
46
+ ```bash
47
+ python app.py
48
+ tivelweb serve dist
49
+ ```
50
+
51
+ Open `http://127.0.0.1:8000`.
52
+
53
+ ## Commands
54
+
55
+ ```bash
56
+ tivelweb new mywebsite
57
+ cd mywebsite
58
+ python app.py
59
+ tivelweb serve dist
60
+ ```
61
+
62
+ ## Features
63
+
64
+ - Responsive pages and navigation
65
+ - Hero, section, card, button, and image components
66
+ - Multiple pages
67
+ - Custom theme colors
68
+ - Static asset copying
69
+ - Built-in local preview server
70
+ - No runtime dependencies
71
+
72
+ ## Test
73
+
74
+ ```bash
75
+ python -m unittest discover -s tests
76
+ ```
77
+
78
+ ## License
79
+
80
+ MIT
81
+
@@ -0,0 +1,63 @@
1
+ # TivelWeb
2
+
3
+ TivelWeb is a lightweight Python library for building responsive static websites without writing all the HTML and CSS yourself.
4
+
5
+ ## Install locally
6
+
7
+ ```bash
8
+ cd tivelweb
9
+ python -m venv .venv
10
+ source .venv/bin/activate
11
+ pip install -e .
12
+ ```
13
+
14
+ ## Build your first website
15
+
16
+ ```python
17
+ from tivelweb import Site, hero, section
18
+
19
+ site = Site("My Website", theme_color="#6c5ce7")
20
+ home = site.page("Home", description="My first Python website")
21
+ home.add(hero("Welcome", "This website was built using Python.", "Learn more", "#about"))
22
+ home.add(section("About", "TivelWeb generates fast static HTML."))
23
+ site.build()
24
+ ```
25
+
26
+ Run the file, then preview the generated `dist` folder:
27
+
28
+ ```bash
29
+ python app.py
30
+ tivelweb serve dist
31
+ ```
32
+
33
+ Open `http://127.0.0.1:8000`.
34
+
35
+ ## Commands
36
+
37
+ ```bash
38
+ tivelweb new mywebsite
39
+ cd mywebsite
40
+ python app.py
41
+ tivelweb serve dist
42
+ ```
43
+
44
+ ## Features
45
+
46
+ - Responsive pages and navigation
47
+ - Hero, section, card, button, and image components
48
+ - Multiple pages
49
+ - Custom theme colors
50
+ - Static asset copying
51
+ - Built-in local preview server
52
+ - No runtime dependencies
53
+
54
+ ## Test
55
+
56
+ ```bash
57
+ python -m unittest discover -s tests
58
+ ```
59
+
60
+ ## License
61
+
62
+ MIT
63
+
@@ -0,0 +1,29 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "tivelweb"
7
+ version = "0.1.0"
8
+ description = "Build responsive static websites using friendly Python code."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = {text = "MIT"}
12
+ authors = [{name = "tivalsdeveloper"}]
13
+ keywords = ["website", "static-site-generator", "html", "python"]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+
20
+ [project.urls]
21
+ Homepage = "https://github.com/tivalsdeveloper-oss/tivelweb"
22
+ Repository = "https://github.com/tivalsdeveloper-oss/tivelweb"
23
+ Issues = "https://github.com/tivalsdeveloper-oss/tivelweb/issues"
24
+
25
+ [project.scripts]
26
+ tivelweb = "tivelweb.cli:main"
27
+
28
+ [tool.setuptools.packages.find]
29
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,8 @@
1
+ """TivelWeb public API."""
2
+
3
+ from .components import button, card, hero, image, section
4
+ from .site import Page, Site
5
+
6
+ __all__ = ["Site", "Page", "hero", "section", "card", "button", "image"]
7
+ __version__ = "0.1.0"
8
+
@@ -0,0 +1,37 @@
1
+ """TivelWeb command line interface."""
2
+
3
+ import argparse
4
+ from http.server import ThreadingHTTPServer, SimpleHTTPRequestHandler
5
+ from pathlib import Path
6
+ import os
7
+
8
+
9
+ STARTER = '''from tivelweb import Site, hero, section
10
+
11
+ site = Site("My Website")
12
+ home = site.page("Home", description="My first TivelWeb website")
13
+ home.add(hero("Built with Python", "A fast responsive website.", "Get started", "#about"))
14
+ home.add(section("About", "Edit app.py to make this website yours."))
15
+ print(f"Website built at: {site.build()}")
16
+ '''
17
+
18
+
19
+ def main() -> None:
20
+ parser = argparse.ArgumentParser(prog="tivelweb")
21
+ sub = parser.add_subparsers(dest="command", required=True)
22
+ new = sub.add_parser("new", help="create a starter project")
23
+ new.add_argument("name")
24
+ serve = sub.add_parser("serve", help="preview a built website")
25
+ serve.add_argument("directory", nargs="?", default="dist")
26
+ serve.add_argument("--port", type=int, default=8000)
27
+ args = parser.parse_args()
28
+ if args.command == "new":
29
+ folder = Path(args.name)
30
+ folder.mkdir(parents=True, exist_ok=True)
31
+ (folder / "app.py").write_text(STARTER, encoding="utf-8")
32
+ print(f"Created {folder.resolve()}")
33
+ else:
34
+ os.chdir(args.directory)
35
+ print(f"Serving http://127.0.0.1:{args.port} — press Ctrl+C to stop")
36
+ ThreadingHTTPServer(("127.0.0.1", args.port), SimpleHTTPRequestHandler).serve_forever()
37
+
@@ -0,0 +1,35 @@
1
+ """Safe, reusable HTML components."""
2
+
3
+ from html import escape
4
+
5
+
6
+ def _text(value: object) -> str:
7
+ return escape(str(value), quote=True)
8
+
9
+
10
+ def button(label: str, href: str = "#", style: str = "primary") -> str:
11
+ return f'<a class="btn btn-{_text(style)}" href="{_text(href)}">{_text(label)}</a>'
12
+
13
+
14
+ def image(src: str, alt: str = "", class_name: str = "") -> str:
15
+ return f'<img src="{_text(src)}" alt="{_text(alt)}" class="{_text(class_name)}" loading="lazy">'
16
+
17
+
18
+ def hero(title: str, subtitle: str = "", action: str = "", action_url: str = "#") -> str:
19
+ action_html = button(action, action_url) if action else ""
20
+ return (
21
+ '<section class="hero"><div class="container">'
22
+ f'<h1>{_text(title)}</h1><p>{_text(subtitle)}</p>{action_html}'
23
+ '</div></section>'
24
+ )
25
+
26
+
27
+ def section(title: str, content: str, *, raw: bool = False) -> str:
28
+ body = content if raw else f"<p>{_text(content)}</p>"
29
+ return f'<section class="section"><div class="container"><h2>{_text(title)}</h2>{body}</div></section>'
30
+
31
+
32
+ def card(title: str, content: str, link: str = "", link_text: str = "Learn more") -> str:
33
+ link_html = button(link_text, link, "secondary") if link else ""
34
+ return f'<article class="card"><h3>{_text(title)}</h3><p>{_text(content)}</p>{link_html}</article>'
35
+
@@ -0,0 +1,67 @@
1
+ """Website and page builders."""
2
+
3
+ from dataclasses import dataclass, field
4
+ from html import escape
5
+ from pathlib import Path
6
+ import shutil
7
+
8
+
9
+ DEFAULT_CSS = """:root{--primary:#6c5ce7;--dark:#151522;--light:#f7f7fb;--text:#29293d;--radius:18px}*{box-sizing:border-box}body{margin:0;font-family:system-ui,-apple-system,sans-serif;color:var(--text);background:var(--light);line-height:1.65}a{color:inherit}.container{width:min(1100px,92%);margin:auto}.navbar{background:var(--dark);color:white;padding:1rem 0}.navbar .container{display:flex;justify-content:space-between;align-items:center;gap:1rem}.brand{font-size:1.25rem;font-weight:800;text-decoration:none}.nav-links{display:flex;gap:1rem;flex-wrap:wrap}.nav-links a{text-decoration:none}.hero{padding:6rem 0;text-align:center;background:linear-gradient(135deg,#151522,#6c5ce7);color:white}.hero h1{font-size:clamp(2.4rem,7vw,5rem);line-height:1.05;margin:0}.hero p{font-size:1.2rem;opacity:.9}.section{padding:4rem 0}.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:1.25rem}.card{background:white;padding:1.5rem;border-radius:var(--radius);box-shadow:0 12px 35px #1d1d3512}.btn{display:inline-block;padding:.75rem 1.1rem;border-radius:999px;text-decoration:none;font-weight:700;margin-top:.5rem}.btn-primary{background:white;color:var(--primary)}.btn-secondary{background:var(--primary);color:white}.footer{padding:2rem;background:var(--dark);color:#ccc;text-align:center}@media(max-width:600px){.navbar .container{align-items:flex-start;flex-direction:column}.hero{padding:4rem 0}}"""
10
+
11
+
12
+ @dataclass
13
+ class Page:
14
+ title: str
15
+ path: str = "index.html"
16
+ description: str = ""
17
+ content: list[str] = field(default_factory=list)
18
+
19
+ def add(self, html: str) -> "Page":
20
+ self.content.append(html)
21
+ return self
22
+
23
+
24
+ class Site:
25
+ def __init__(self, name: str, *, theme_color: str = "#6c5ce7", output: str = "dist"):
26
+ self.name = name
27
+ self.theme_color = theme_color
28
+ self.output = Path(output)
29
+ self.pages: list[Page] = []
30
+ self.assets: list[tuple[Path, str]] = []
31
+
32
+ def page(self, title: str, path: str = "index.html", description: str = "") -> Page:
33
+ page = Page(title, path, description)
34
+ self.pages.append(page)
35
+ return page
36
+
37
+ def add_asset(self, source: str, destination: str = "assets") -> "Site":
38
+ self.assets.append((Path(source), destination))
39
+ return self
40
+
41
+ def _render(self, page: Page) -> str:
42
+ links = "".join(
43
+ f'<a href="/{escape(p.path, quote=True)}">{escape(p.title)}</a>' for p in self.pages
44
+ )
45
+ body = "\n".join(page.content)
46
+ css = DEFAULT_CSS.replace("#6c5ce7", self.theme_color)
47
+ return f"""<!doctype html>
48
+ <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
49
+ <title>{escape(page.title)} | {escape(self.name)}</title><meta name="description" content="{escape(page.description, quote=True)}">
50
+ <style>{css}</style></head><body>
51
+ <nav class="navbar"><div class="container"><a class="brand" href="/">{escape(self.name)}</a><div class="nav-links">{links}</div></div></nav>
52
+ <main>{body}</main><footer class="footer">Powered by tivalsdeveloper</footer></body></html>"""
53
+
54
+ def build(self, clean: bool = True) -> Path:
55
+ if clean and self.output.exists():
56
+ shutil.rmtree(self.output)
57
+ self.output.mkdir(parents=True, exist_ok=True)
58
+ for page in self.pages:
59
+ target = self.output / page.path
60
+ target.parent.mkdir(parents=True, exist_ok=True)
61
+ target.write_text(self._render(page), encoding="utf-8")
62
+ for source, destination in self.assets:
63
+ target = self.output / destination / source.name
64
+ target.parent.mkdir(parents=True, exist_ok=True)
65
+ shutil.copy2(source, target)
66
+ return self.output.resolve()
67
+
@@ -0,0 +1,81 @@
1
+ Metadata-Version: 2.4
2
+ Name: tivelweb
3
+ Version: 0.1.0
4
+ Summary: Build responsive static websites using friendly Python code.
5
+ Author: tivalsdeveloper
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/tivalsdeveloper-oss/tivelweb
8
+ Project-URL: Repository, https://github.com/tivalsdeveloper-oss/tivelweb
9
+ Project-URL: Issues, https://github.com/tivalsdeveloper-oss/tivelweb/issues
10
+ Keywords: website,static-site-generator,html,python
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Requires-Python: >=3.9
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Dynamic: license-file
18
+
19
+ # TivelWeb
20
+
21
+ TivelWeb is a lightweight Python library for building responsive static websites without writing all the HTML and CSS yourself.
22
+
23
+ ## Install locally
24
+
25
+ ```bash
26
+ cd tivelweb
27
+ python -m venv .venv
28
+ source .venv/bin/activate
29
+ pip install -e .
30
+ ```
31
+
32
+ ## Build your first website
33
+
34
+ ```python
35
+ from tivelweb import Site, hero, section
36
+
37
+ site = Site("My Website", theme_color="#6c5ce7")
38
+ home = site.page("Home", description="My first Python website")
39
+ home.add(hero("Welcome", "This website was built using Python.", "Learn more", "#about"))
40
+ home.add(section("About", "TivelWeb generates fast static HTML."))
41
+ site.build()
42
+ ```
43
+
44
+ Run the file, then preview the generated `dist` folder:
45
+
46
+ ```bash
47
+ python app.py
48
+ tivelweb serve dist
49
+ ```
50
+
51
+ Open `http://127.0.0.1:8000`.
52
+
53
+ ## Commands
54
+
55
+ ```bash
56
+ tivelweb new mywebsite
57
+ cd mywebsite
58
+ python app.py
59
+ tivelweb serve dist
60
+ ```
61
+
62
+ ## Features
63
+
64
+ - Responsive pages and navigation
65
+ - Hero, section, card, button, and image components
66
+ - Multiple pages
67
+ - Custom theme colors
68
+ - Static asset copying
69
+ - Built-in local preview server
70
+ - No runtime dependencies
71
+
72
+ ## Test
73
+
74
+ ```bash
75
+ python -m unittest discover -s tests
76
+ ```
77
+
78
+ ## License
79
+
80
+ MIT
81
+
@@ -0,0 +1,13 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/tivelweb/__init__.py
5
+ src/tivelweb/cli.py
6
+ src/tivelweb/components.py
7
+ src/tivelweb/site.py
8
+ src/tivelweb.egg-info/PKG-INFO
9
+ src/tivelweb.egg-info/SOURCES.txt
10
+ src/tivelweb.egg-info/dependency_links.txt
11
+ src/tivelweb.egg-info/entry_points.txt
12
+ src/tivelweb.egg-info/top_level.txt
13
+ tests/test_tivelweb.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ tivelweb = tivelweb.cli:main
@@ -0,0 +1 @@
1
+ tivelweb
@@ -0,0 +1,21 @@
1
+ from pathlib import Path
2
+ from tempfile import TemporaryDirectory
3
+ import unittest
4
+
5
+ from tivelweb import Site, hero
6
+
7
+
8
+ class SiteTests(unittest.TestCase):
9
+ def test_builds_page(self):
10
+ with TemporaryDirectory() as folder:
11
+ site = Site("Test", output=folder)
12
+ site.page("Home").add(hero("Hello"))
13
+ site.build()
14
+ html = (Path(folder) / "index.html").read_text()
15
+ self.assertIn("Hello", html)
16
+ self.assertIn("Powered by tivalsdeveloper", html)
17
+
18
+
19
+ if __name__ == "__main__":
20
+ unittest.main()
21
+