Skip to content

Commit afd950a

Browse files
committed
Updated docs
1 parent e13a887 commit afd950a

File tree

15 files changed

+346
-151
lines changed

15 files changed

+346
-151
lines changed

docs/assets/stylesheets/home.css

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55

66
#home-hero {
77
position: relative;
8-
height: 650px;
9-
max-height: 100vh;
108
margin-top: -2.5rem;
119

1210
svg {
@@ -39,7 +37,7 @@
3937
color: #fff;
4038
text-align: center;
4139
max-width: 1000px;
42-
margin: 4.5rem auto 0;
40+
margin: 4.5rem auto 2rem;
4341
h1 {
4442
font-family: "Poppins", sans-serif;
4543
font-size: 2.5rem;
@@ -88,11 +86,10 @@
8886
padding: 2rem 0;
8987

9088
> div {
91-
display: grid;
92-
grid-template-columns: 1fr 1fr 1fr;
9389
gap: 2rem;
9490
margin: 0 auto;
9591
max-width: 1220px;
92+
padding: 0 .8rem;
9693

9794
h2 {
9895
font-size: 1.5rem;
@@ -115,6 +112,14 @@
115112
}
116113
}
117114

115+
@media (min-width: 768px) {
116+
#home-intro > div {
117+
display: grid;
118+
grid-template-columns: 1fr 1fr 1fr;
119+
padding: 0;
120+
}
121+
}
122+
118123
#home-technos {
119124
display: flex;
120125
flex-wrap: wrap;
@@ -132,8 +137,6 @@
132137
}
133138

134139
.home-feature {
135-
display: grid;
136-
grid-template-columns: 1fr 1fr;
137140
gap: 2rem;
138141

139142
h2 {
@@ -149,14 +152,30 @@
149152
img {
150153
display: block;
151154
margin: 0 auto;
152-
max-width: 600px;
153155
max-height: 300px;
156+
max-width: 100%;
154157
}
155158
}
156159
.home-feature + .home-feature {
157160
margin-top: 4rem;
158161
}
159162

163+
@media (min-width: 768px) {
164+
.home-feature {
165+
display: grid;
166+
grid-template-columns: 1fr 1fr;
167+
168+
img {
169+
max-width: 600px;
170+
}
171+
}
172+
.home-feature:nth-child(odd) {
173+
> div:first-child {
174+
order: 2;
175+
}
176+
}
177+
}
178+
160179
.md-tabs {
161180
margin-top: 2.5rem;
162181
color: #fff;

docs/components/layout.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Layout
2+
3+
Hyperflask includes a few utilties to help you design your app quickly.
4+
5+
## Common app UI
6+
7+
Use the following snippet to kick start a very common application UI with a sidebar:
8+
9+
```
10+
<{AppUI}>
11+
<{Viewport}>
12+
13+
</{Viewport}>
14+
<{Sidebar}>
15+
16+
</{Sidebar}>
17+
</{AppUI}>
18+
```
19+
20+
Use the [Menu](/components/daisyui/Menu) component to create menus in the sidebar.
21+
22+
Viewport is a vertical flexbox with overflow by default. Use `<{Viewport overflow=False}>` for no overflowing.
23+
24+
## Flex boxes
25+
26+
Use `<{HBox}>` and `<{VBox}>` for respectively row and column flexbox with a gap between each items.
27+
28+
Use `<{CenterBox}>` for a box which content is vertically and horizontally centered.
29+
30+
Use `<{Spacer}/>` to add a growing div that takes all the space between 2 items.

docs/getting-started.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ def post():
224224
current_app.sse.publish("messages", current_app.components.ChatMessage(message=msg), private=True)
225225
---
226226
{% form %}
227-
<{HxForm form action=url_for("PostMessageForm") hx_swap="outerHTML"}>
227+
<{HxForm form action=url_for("PostMessageForm") hx_swap="none"}>
228228
<{FormField form.message.textarea(required=True, placeholder="Chat") }/>
229229
<{SubmitButton}>Send</{}>
230230
</{HxForm}>
@@ -239,7 +239,7 @@ from app.models import Message
239239
page.messages = Message.find_all()
240240
---
241241
{% use_layout %}
242-
<{MercureStream topic="messages" id="messages"}>
242+
<{MercureStream topic="messages"}>
243243
{% for msg in messages %}
244244
<{ChatMessage message=msg }/>
245245
{% endfor %}
@@ -285,6 +285,8 @@ Modify the component `ChatMessage` to display the author:
285285

286286
Finally, add `page.login_required()` at the top of your page frontmatter to require authentication to access it.
287287

288+
Upon accessing your site, you will be asked to connect using an email address. No confirmation will be asked on first connection. On further connections, you will be asked for a code to complete the connection. Go to <http://localhost:8025> to access [Mailpit](https://github.com/axllent/mailpit) and read the emails.
289+
288290
## Deploying to production
289291

290292
Signup for an account on Fly.io or any VPS provider (eg: Digital Ocean) then run the following command from a VS Code terminal (while connected to the dev container):

docs/guides/components.md

Lines changed: 20 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -86,114 +86,6 @@ Example using the previous *app/components/Dropdown.html*:
8686
</div>
8787
```
8888

89-
## Backend logic and interactions with HTMX
90-
91-
Components can define their own custom backend logic. Similar to pages, files should use the *jpy* extension and provide a frontmatter with the python code.
92-
93-
Functions named after HTTP methods will be registered as routes. For example, if a *get* function exists, Hyperflask will make the component accessible through GET requests.
94-
These functions can return a dict with component props to render the component or any other valid Flask response value.
95-
96-
Use HTMX to call your component logic and retrieve only the necessery HTML.
97-
98-
Let's create a todo app:
99-
100-
*app/pages/index.jpy*:
101-
102-
```
103-
---
104-
from app.models import Todo
105-
page.todos = Todo.find_all()
106-
---
107-
<table>
108-
{% for todo in todos %}
109-
<{TodoItem todo=todo }/>
110-
{% endfor %}
111-
</table>
112-
<button hx-get="{{url_for('TodoItemForm')}}" hx-target="previous" hx-swap="beforeend">Add todo</button>
113-
```
114-
115-
*app/components/TodoItem.jpy*:
116-
117-
```
118-
---
119-
from app.models import db, Todo
120-
121-
def get():
122-
todo = Todo.get_or_404(request.args['id'])
123-
return {"todo": todo}
124-
125-
def delete():
126-
with db:
127-
todo = Todo.get_or_404(request.args['id'])
128-
todo.delete()
129-
return ""
130-
---
131-
<tr>
132-
<td>{{props.todo.title}}</td>
133-
<td>
134-
<button hx-get="{{url_for('TodoItemForm', id=props.todo.id)}}" hx-target="closest tr" hx-swap="outerHTML">Delete</button>
135-
<button hx-delete="{{url_for('TodoItem', id=props.todo.id)}}" hx-target="closest tr" hx-swap="delete">Delete</button>
136-
</td>
137-
</tr>
138-
```
139-
140-
*app/components/TodoItemForm.jpy*:
141-
142-
```
143-
---
144-
from hyperflask import request, current_app
145-
from app.models import db, Todo
146-
147-
def get():
148-
todo = Todo.get_or_404(request.args['id']) if "id" in request.args else None
149-
return {"todo": todo}
150-
151-
def post():
152-
with db:
153-
if "id" in request.values:
154-
todo = Todo.get_or_404(request.args['id'])
155-
else:
156-
todo = Todo()
157-
todo.title = request.form["title"]
158-
todo.save()
159-
return current_app.components.TodoItem(todo=todo) # return another component
160-
---
161-
<tr>
162-
<td>
163-
<input type="text" name="title" value="{{props.todo.title if props.todo else ''}}" required>
164-
</td>
165-
<td>
166-
<button hx-get="{{url_for('TodoItemForm', id=props.todo.id if props.todo else None)}}" hx-include="closest tr" hx-target="closest tr" hx-swap="outerHTML">Save</button>
167-
</td>
168-
</tr>
169-
```
170-
171-
!!! warning
172-
Unlike pages, all python imports are mandatory in components
173-
174-
!!! tip
175-
The `request` object in Hyperflask uses [htmx-Flask](https://github.com/sponsfreixes/htmx-flask) subclass that [provides easy access to htmx headers](https://github.com/sponsfreixes/htmx-flask?tab=readme-ov-file#usage).
176-
177-
### HTMX utilities
178-
179-
Perform an htmx redirection using `htmx_redirect()`:
180-
181-
```py
182-
from hyperflask import htmx_redirect
183-
def post():
184-
# ...
185-
return htmx_redirect("/")
186-
```
187-
188-
Perform an Out-Of-Band (oob) swap using `htmx_oob()`:
189-
190-
```py
191-
from hyperflask import htmx_oob
192-
def post():
193-
# ...
194-
return htmx_oob(current_app.components.Sidebar()) # replaces the sidebar element with a new version of itself
195-
```
196-
19789
## Styling and scripting
19890

19991
Scripts and styles can be embedded in components and bundled automatically.
@@ -231,7 +123,7 @@ In a template: `<{custom_dropdown}/>`
231123

232124
### React components
233125

234-
Define react components as usual in a jsx file named after the component. Call them in your template like any other component. Each component call will create an independant react tree.
126+
Define react components as usual in a jsx file named after the component. You must export your component as default. Call them in your template like any other component. Each component call will create an independant react tree.
235127

236128
!!! important
237129
React is not bundled with Hyperflask. You will need to install it using npm.
@@ -241,7 +133,7 @@ Properties provided to the component will be serialized to JSON. You cannot prov
241133
Example, *app/components/Dropdown.jsx*:
242134

243135
```js
244-
function Dropdown(props) {
136+
export default function Dropdown(props) {
245137
return <div></div>;
246138
}
247139
```
@@ -252,4 +144,21 @@ In a template: `<{Dropdown}/>`
252144

253145
Hyperflask includes a rich library of UI components powered by [DaisyUI](https://daisyui.com).
254146

255-
Check out the [Components library](/components)
147+
Check out the [Components library](/components)
148+
149+
## Components with custom logic
150+
151+
For backend components, you can execute business logic before rendering the template.
152+
Use a jinjapy file instead of html file (.jpy extension) and implement the render function.
153+
154+
The render function will be provided the props as arguments.
155+
156+
```
157+
---
158+
def render(prop1, prop2):
159+
# custom logic
160+
return {"var": "value"} # template variables
161+
---
162+
{{var}}
163+
---
164+
```

docs/guides/config.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,21 @@ An environment specific *.env* file can also be created following the format *.e
2626

2727
## Common configuration values
2828

29-
| Key | Description | Default location | Default value |
29+
See [Flask documentation](https://flask.palletsprojects.com/en/stable/config/#builtin-configuration-values) for the full list of Flask options.
30+
31+
Each Flask extension may have their own configuration.
32+
33+
| Key | Type | Description | Default value |
3034
| --- | --- | --- | --- |
31-
| SECRET_KEY | The encryption key for all secret values (including the session) | .env | random
35+
| SECRET_KEY | str | The encryption key for all secret values (including the session) (set by default in .env) | random
36+
| SITE_TITLE | str | |
37+
| SITE_LANG | str | |
38+
| ASSETS_INCLUDE_HTMX | bool | |
39+
| HTMX_EXT | list[str] | |
40+
| HTMX_BOOST_SITE | bool | |
41+
| EMAIL_BACKGROUND_COLOR | str | |
42+
| EMAIL_BACKGROUND_ACCENT_COLOR | str | |
43+
| STATIC_MODE | str | |
44+
| MARKDOWN_OPTIONS | dict | |
45+
| FLASH_TOAST_OOB | bool | Whether to add flash messages to htmx request as oob swaps |
46+
| FLASH_TOAST_REMOVE_AFTER | str | Use the remove-me htmx extension to auto remove the toast alerts after some time |

docs/guides/deploy.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,14 @@
33
!!! info
44
This feature is provided by [Docker Web Deploy](https://github.com/hyperflask/docker-web-deploy)
55

6+
## Build & deploy
7+
68
Run the following command:
79

810
```
9-
$ hyperflask deploy
10-
```
11+
$ uv run hyperflask deploy
12+
```
13+
14+
## Build only
15+
16+
When using Hyperflask-Start, the app is containerized. Run `docker build .` to build the image.

docs/guides/flash.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Flash messages
2+
3+
Flask [provides a mechanism](https://flask.palletsprojects.com/en/stable/patterns/flashing/) for showing one time messages to the user.
4+
5+
Use `flash()` or `page.flash()` as described by Flask documentation.
6+
7+
Hyperflask will automatically print the messages as [alert messages in a toast](https://daisyui.com/components/toast/). This will also work when flashing messages during ajax requests.

0 commit comments

Comments
 (0)