Skip to content

Commit 7f4fc4a

Browse files
committed
feat(project): update project metadata and enhance README with features and usage examples
1 parent 1183c29 commit 7f4fc4a

3 files changed

Lines changed: 92 additions & 34 deletions

File tree

README.md

Lines changed: 82 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@
99

1010
---
1111

12+
## ✨ Features
13+
14+
- Flexible text composition from components
15+
- Conditional rendering support (`when`)
16+
- Grouping and repeating blocks
17+
- Formatting via f-string and Jinja2
18+
- Easily extensible with new components
19+
20+
---
21+
1222
## 🚀 Installation
1323

1424
You can install the library in two ways:
@@ -26,63 +36,105 @@ pip install textcompose
2636

2737
---
2838

39+
2940
## 💻 Usage
3041

3142
### Components Overview
3243

33-
`TextCompose` provides the following core components:
44+
#### General
45+
46+
- `Template` — combines and renders components as a structured text block.
47+
48+
#### Content Blocks
49+
50+
- `BaseContent` — abstract base class for all content components
51+
52+
53+
- `Text` — outputs static text
54+
- `Format` — dynamic formatting via f-string
55+
- `Jinja` — rendering via Jinja2 templates
3456

35-
1. **`Template`**: Combines and renders components as a structured text block.
36-
2. **`Group`**: Groups multiple components and joins their output with a separator (`sep`).
37-
3. **`Text`**: Displays static text.
38-
4. **`Format`**: Formats strings dynamically using a given context.
57+
#### Containers
3958

40-
All components support the `when` parameter for conditional rendering. If `when` evaluates to `True`, the component is rendered; otherwise, it is skipped.
59+
- `BaseContainer` — abstract base class for containers
4160

42-
### Example
4361

44-
Below is an example of how to use `TextCompose` to create dynamic text templates with nested components and conditional rendering.
62+
- `Group` — groups children with a separator
63+
- `List` — repeats a template for a collection
64+
65+
#### Logic Components
66+
67+
- `If` — conditional rendering (`if_`, `then_`, `else_`)
68+
69+
All components support the `when` parameter for conditional rendering.
70+
71+
---
72+
73+
## 📝 Examples
74+
75+
### Example 1: Simple composition
4576

4677
```python
78+
from magic_filter import F
79+
4780
from textcompose import Template
48-
from textcompose.container import Group
49-
from textcompose.content import Format, Text
81+
from textcompose.container import Group, List
82+
from textcompose.content import Format, Text, Jinja
83+
from textcompose.logic import If
5084

51-
# Create a template using nested components
5285
template = Template(
86+
Format("Hello, {name}!"),
87+
Format("Status: {status}"), # or `lambda ctx: f"Status: {ctx['status']}"` with function
88+
If(
89+
F["notifications"] > 0, # `if_` - condition to check if there are notifications
90+
Format("You have {notifications} new notifications."), # `then_` - content to render if condition is True
91+
Format("You not have new notifications."), # `else_` - content to render if condition is False
92+
),
5393
Group(
54-
Format("Hello, {name}!"),
55-
Format("Your status: {status}."),
56-
Group(
57-
Text("You have new notifications."),
58-
Format("Notification count: {notifications}.", when=lambda ctx: ctx.get("notifications") > 0),
59-
sep=" " # Separator for the nested group
94+
Jinja("\nTotal messages {{ messages|length }}:"),
95+
List(
96+
Format("Time - {item[time]}:"),
97+
Format("- {item[text]}"),
98+
sep="\n", # `sep` - separator between list items
99+
inner_sep="\n", # `inner_sep` - separator between parts of a single item
100+
getter=lambda ctx: ctx["messages"], # `getter` - function or F to extract the list of messages from context
60101
),
61-
sep="\n" # Separator for the main group
62-
)
102+
sep="\n", # `sep` - separator between children of Group
103+
when=F["messages"].len() > 0, # `when` - show this block only if there are messages
104+
),
105+
Text("\nThank you for using our service!"), # or "Recent messages:" without class
63106
)
64107

65-
# Context for rendering
66108
context = {
67-
"name": "John",
109+
"name": "Alexey",
68110
"status": "Online",
69-
"notifications": 3
111+
"notifications": 2,
112+
"messages": [
113+
{"text": "Your package has been delivered.", "time": "09:15"},
114+
{"text": "Reminder: meeting tomorrow at 10:00.", "time": "18:42"},
115+
],
70116
}
71117

72-
# Render text
73-
result = template.render(context)
74-
print(result)
118+
print(template.render(context))
75119
```
76120

77-
### Output:
121+
**Output:**
78122
```
79-
Hello, John!
80-
Your status: Online.
81-
You have new notifications. Notification count: 3.
123+
Hello, Alexey!
124+
Status: Online
125+
You have 2 new notifications.
126+
127+
Total messages 2:
128+
Time - 09:15:
129+
- Your package has been delivered.
130+
Time - 18:42:
131+
- Reminder: meeting tomorrow at 10:00.
132+
133+
Thank you for using our service!
82134
```
83135

84136
---
85137

86138
## 👨‍💻 Contributing
87139

88-
We welcome contributions to `TextCompose`. If you have suggestions or improvements, please open an issue or submit a pull request.
140+
We welcome contributions to `TextCompose`. If you have suggestions or improvements, please open an issue or submit a pull request.

pyproject.toml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
[project]
22
name = "textcompose"
3-
description = "A Python library for building dynamic, structured text templates using a declarative, compose-based approach"
43
version = "0.6.1"
4+
description = "A Python library for building dynamic, structured text templates using a declarative, compose-based approach"
55
readme = "README.md"
66
license = { text = "Apache-2.0" }
77
authors = [
88
{ name = "m-xim", email = "i@m-xim.ru" },
99
]
1010
requires-python = ">=3.10"
11+
packages = [{ include = "textcompose" }]
1112
dependencies = [
1213
"jinja2>=3.1.6",
1314
"magic-filter>=1.0.12",
1415
]
16+
1517
keywords = [
1618
"template",
1719
"text generation",
@@ -39,10 +41,14 @@ Issues = "https://github.com/m-xim/textcompose/issues"
3941

4042
[dependency-groups]
4143
dev = [
42-
"ruff",
43-
"pytest",
44+
"ruff",
45+
"pytest",
4446
]
4547

48+
[build-system]
49+
requires = ["hatchling"]
50+
build-backend = "hatchling.build"
51+
4652
[tool.ruff]
4753
line-length = 120
4854

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)