tina4-python 3.9.2__tar.gz → 3.10.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.
- {tina4_python-3.9.2 → tina4_python-3.10.0}/PKG-INFO +1 -1
- {tina4_python-3.9.2 → tina4_python-3.10.0}/pyproject.toml +1 -1
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/CLAUDE.md +11 -2
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/core/response.py +75 -21
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/core/server.py +12 -17
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/messenger/__init__.py +2 -3
- {tina4_python-3.9.2 → tina4_python-3.10.0}/.gitignore +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/README.md +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/HtmlElement.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/Testing.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/ai/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/api/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/auth/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/cache/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/cli/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/container/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/core/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/core/cache.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/core/constants.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/core/events.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/core/middleware.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/core/request.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/core/router.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/crud/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/database/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/database/adapter.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/database/connection.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/database/firebird.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/database/mssql.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/database/mysql.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/database/odbc.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/database/postgres.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/database/sqlite.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/debug/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/debug/error_overlay.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/dev_admin/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/dev_reload.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/dotenv/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/frond/FROND.md +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/frond/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/frond/engine.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/auth/meta.json +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/auth/src/routes/api/gallery_auth.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/database/meta.json +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/database/src/routes/api/gallery_db.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/error-overlay/meta.json +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/error-overlay/src/routes/api/gallery_crash.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/orm/meta.json +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/orm/src/orm/Product.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/orm/src/routes/api/gallery_products.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/queue/meta.json +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/queue/src/routes/api/gallery_queue.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/rest-api/meta.json +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/rest-api/src/routes/api/gallery_hello.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/templates/meta.json +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/templates/src/routes/gallery_page.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/templates/src/templates/gallery_page.twig +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/graphql/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/i18n/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/migration/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/migration/runner.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/orm/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/orm/fields.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/orm/model.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/public/css/tina4.css +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/public/css/tina4.min.css +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/public/favicon.ico +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/public/images/logo.svg +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/public/images/tina4-logo-icon.webp +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/public/js/frond.min.js +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/public/js/tina4-dev-admin.min.js +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/public/js/tina4.min.js +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/public/js/tina4js.min.js +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/public/swagger/index.html +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/public/swagger/oauth2-redirect.html +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/query_builder/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/queue/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/queue_backends/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/queue_backends/kafka_backend.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/queue_backends/mongo_backend.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/queue_backends/rabbitmq_backend.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/scss/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/scss/tina4css/_alerts.scss +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/scss/tina4css/_badges.scss +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/scss/tina4css/_buttons.scss +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/scss/tina4css/_cards.scss +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/scss/tina4css/_forms.scss +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/scss/tina4css/_grid.scss +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/scss/tina4css/_modals.scss +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/scss/tina4css/_nav.scss +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/scss/tina4css/_reset.scss +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/scss/tina4css/_tables.scss +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/scss/tina4css/_typography.scss +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/scss/tina4css/_utilities.scss +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/scss/tina4css/_variables.scss +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/scss/tina4css/base.scss +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/scss/tina4css/colors.scss +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/scss/tina4css/tina4.scss +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/seeder/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/service/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/session/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/session_handlers/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/session_handlers/mongodb_handler.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/session_handlers/redis_handler.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/session_handlers/valkey_handler.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/swagger/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/templates/components/crud.twig +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/templates/docker/distroless/Dockerfile +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/templates/docker/poetry/Dockerfile +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/templates/docker/python/Dockerfile +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/templates/docker/uv/Dockerfile +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/templates/errors/302.twig +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/templates/errors/401.twig +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/templates/errors/403.twig +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/templates/errors/404.twig +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/templates/errors/500.twig +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/templates/errors/502.twig +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/templates/errors/503.twig +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/templates/errors/base.twig +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/templates/frontend/README.md +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/templates/readme.md +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/test_client/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/af/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/af/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/en/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/es/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/es/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/fr/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/ja/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/ja/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/zh/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/zh/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/validator/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/websocket/__init__.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/websocket/backplane.py +0 -0
- {tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/wsdl/__init__.py +0 -0
|
@@ -233,7 +233,7 @@ Tina4 provides a full toolkit. Before writing custom code, check if the framewor
|
|
|
233
233
|
| GraphQL API | `GraphQL` from `tina4_python.graphql` |
|
|
234
234
|
| SOAP/WSDL services | `WSDL` from `tina4_python.wsdl` |
|
|
235
235
|
| Database migrations | `migrate`, `create_migration` from `tina4_python.migration` |
|
|
236
|
-
| WebSockets | `WebSocketServer` from `tina4_python.websocket` |
|
|
236
|
+
| WebSockets | `WebSocketServer` from `tina4_python.websocket`. Backplane via Redis pub/sub (`TINA4_WS_BACKPLANE`, `TINA4_WS_BACKPLANE_URL`) |
|
|
237
237
|
| SCSS compilation | Drop `.scss` in `src/scss/` — auto-compiled |
|
|
238
238
|
| Static file serving | Put files in `src/public/` — auto-served |
|
|
239
239
|
| Translations / i18n | `I18n` from `tina4_python.i18n` |
|
|
@@ -336,7 +336,7 @@ tina4_python/ # Core framework package (v3.0.0)
|
|
|
336
336
|
├── migration/ # SQL-file migrations (migrate, create_migration, rollback)
|
|
337
337
|
│ └── runner.py # Migration runner
|
|
338
338
|
├── session/ # Pluggable sessions (Session, FileSessionHandler, DatabaseSessionHandler)
|
|
339
|
-
├── websocket/ # RFC 6455 WebSocket server (WebSocketServer, WebSocketConnection)
|
|
339
|
+
├── websocket/ # RFC 6455 WebSocket server (WebSocketServer, WebSocketConnection, backplane)
|
|
340
340
|
├── graphql/ # Zero-dep GraphQL engine (GraphQL, Schema)
|
|
341
341
|
├── wsdl/ # SOAP 1.1 / WSDL server (WSDL, wsdl_operation)
|
|
342
342
|
├── crud/ # Auto-CRUD REST endpoint generator (AutoCrud)
|
|
@@ -504,6 +504,7 @@ TINA4_SESSION_MONGO_USERNAME= # optional
|
|
|
504
504
|
TINA4_SESSION_MONGO_PASSWORD= # optional
|
|
505
505
|
TINA4_SESSION_MONGO_DB=tina4_sessions # default database
|
|
506
506
|
TINA4_SESSION_MONGO_COLLECTION=sessions # default collection
|
|
507
|
+
TINA4_SESSION_SAMESITE=Lax # SameSite attribute for session cookies (default: Lax)
|
|
507
508
|
```
|
|
508
509
|
|
|
509
510
|
### Authentication & Security
|
|
@@ -836,6 +837,9 @@ result = User().select(filter="name = ?", params=["Alice"], limit=10)
|
|
|
836
837
|
|
|
837
838
|
# Convert to dict
|
|
838
839
|
user.to_dict()
|
|
840
|
+
|
|
841
|
+
# NoSQL support: to_mongo() generates MongoDB query documents from the same fluent API
|
|
842
|
+
result.to_mongo()
|
|
839
843
|
```
|
|
840
844
|
|
|
841
845
|
### Available field types
|
|
@@ -1532,6 +1536,7 @@ HOST_NAME=localhost:7145
|
|
|
1532
1536
|
|
|
1533
1537
|
# Sessions
|
|
1534
1538
|
TINA4_SESSION_HANDLER=SessionFileHandler # SessionFileHandler, SessionRedisHandler, SessionValkeyHandler, SessionMongoHandler
|
|
1539
|
+
TINA4_SESSION_SAMESITE=Lax # SameSite attribute for session cookies (default: Lax)
|
|
1535
1540
|
|
|
1536
1541
|
# Swagger/OpenAPI
|
|
1537
1542
|
SWAGGER_TITLE=Tina4 API # API title (default: "Tina4 API")
|
|
@@ -1768,6 +1773,10 @@ async def dashboard(request, response):
|
|
|
1768
1773
|
- **Messenger**: .env driven SMTP/IMAP
|
|
1769
1774
|
- **ORM relationships**: `has_many`, `has_one`, `belongs_to` with eager loading (`include=`)
|
|
1770
1775
|
- **Frond pre-compilation**: 2.8x template render improvement, `Frond.clear_cache()`
|
|
1776
|
+
- **QueryBuilder** with NoSQL/MongoDB support (`to_mongo()`)
|
|
1777
|
+
- **WebSocket backplane** (Redis pub/sub) for horizontal scaling
|
|
1778
|
+
- **SameSite=Lax** default on session cookies (`TINA4_SESSION_SAMESITE`)
|
|
1779
|
+
- **`tina4 init`** generates Dockerfile and .dockerignore
|
|
1771
1780
|
- **Gallery**: 7 interactive examples with Try It deploy at `/__dev/`
|
|
1772
1781
|
|
|
1773
1782
|
|
|
@@ -22,6 +22,54 @@ import mimetypes
|
|
|
22
22
|
from pathlib import Path
|
|
23
23
|
|
|
24
24
|
|
|
25
|
+
# ---------------------------------------------------------------------------
|
|
26
|
+
# Global Frond template engine registry
|
|
27
|
+
# ---------------------------------------------------------------------------
|
|
28
|
+
_global_frond = None
|
|
29
|
+
_framework_frond = None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def get_frond():
|
|
33
|
+
"""Return the global Frond engine, creating a default if needed."""
|
|
34
|
+
global _global_frond
|
|
35
|
+
if _global_frond is None:
|
|
36
|
+
from tina4_python.frond.engine import Frond
|
|
37
|
+
_global_frond = Frond("src/templates")
|
|
38
|
+
return _global_frond
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def get_framework_frond():
|
|
42
|
+
"""Return the singleton Frond engine for built-in framework templates."""
|
|
43
|
+
global _framework_frond
|
|
44
|
+
framework_dir = Path(__file__).resolve().parent.parent / "templates"
|
|
45
|
+
if _framework_frond is None and framework_dir.is_dir():
|
|
46
|
+
from tina4_python.frond.engine import Frond
|
|
47
|
+
_framework_frond = Frond(str(framework_dir))
|
|
48
|
+
# Sync custom filters/globals from the user engine
|
|
49
|
+
if _framework_frond is not None:
|
|
50
|
+
user_engine = get_frond()
|
|
51
|
+
_framework_frond._filters.update(user_engine._filters)
|
|
52
|
+
_framework_frond._globals.update(user_engine._globals)
|
|
53
|
+
return _framework_frond
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def set_frond(engine):
|
|
57
|
+
"""Register a pre-configured Frond engine for response.render().
|
|
58
|
+
|
|
59
|
+
Call this at startup after registering custom filters and globals:
|
|
60
|
+
|
|
61
|
+
from tina4_python.frond import Frond
|
|
62
|
+
from tina4_python.core.response import set_frond
|
|
63
|
+
|
|
64
|
+
engine = Frond("src/templates")
|
|
65
|
+
engine.add_filter("money", my_money_filter)
|
|
66
|
+
engine.add_global("APP_VERSION", "1.0")
|
|
67
|
+
set_frond(engine)
|
|
68
|
+
"""
|
|
69
|
+
global _global_frond
|
|
70
|
+
_global_frond = engine
|
|
71
|
+
|
|
72
|
+
|
|
25
73
|
class Response:
|
|
26
74
|
"""HTTP response builder with compression and ETag support."""
|
|
27
75
|
|
|
@@ -175,27 +223,33 @@ class Response:
|
|
|
175
223
|
return self
|
|
176
224
|
|
|
177
225
|
def render(self, template: str, data: dict = None) -> "Response":
|
|
178
|
-
"""Render a Frond/Twig template with data.
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
226
|
+
"""Render a Frond/Twig template with data.
|
|
227
|
+
|
|
228
|
+
Uses the global Frond engine (registered via set_frond()) so that
|
|
229
|
+
custom filters and globals are available in all templates.
|
|
230
|
+
Falls back to framework templates if not found in user dir.
|
|
231
|
+
"""
|
|
232
|
+
engine = get_frond()
|
|
233
|
+
|
|
234
|
+
# Try user templates first (the global engine's directory)
|
|
235
|
+
try:
|
|
236
|
+
html = engine.render(template, data or {})
|
|
237
|
+
return self.html(html)
|
|
238
|
+
except FileNotFoundError:
|
|
239
|
+
pass
|
|
240
|
+
except Exception as e:
|
|
241
|
+
return self.html(f"<pre>Template error: {e}</pre>", 500)
|
|
242
|
+
|
|
243
|
+
# Fallback: framework templates (singleton, filters/globals synced)
|
|
244
|
+
fw_engine = get_framework_frond()
|
|
245
|
+
if fw_engine is not None:
|
|
246
|
+
try:
|
|
247
|
+
html = fw_engine.render(template, data or {})
|
|
248
|
+
return self.html(html)
|
|
249
|
+
except FileNotFoundError:
|
|
250
|
+
pass
|
|
251
|
+
except Exception as e:
|
|
252
|
+
return self.html(f"<pre>Template error: {e}</pre>", 500)
|
|
199
253
|
|
|
200
254
|
return self.html(f"<pre>Template not found: {template}</pre>", 404)
|
|
201
255
|
|
|
@@ -105,7 +105,7 @@ def _render_error_page(status_code: int, path: str, request_id: str, error_messa
|
|
|
105
105
|
|
|
106
106
|
Returns rendered HTML string, or None if no template found.
|
|
107
107
|
"""
|
|
108
|
-
from tina4_python.
|
|
108
|
+
from tina4_python.core.response import get_frond, get_framework_frond
|
|
109
109
|
|
|
110
110
|
template_name = f"errors/{status_code}.twig"
|
|
111
111
|
data = {
|
|
@@ -115,21 +115,17 @@ def _render_error_page(status_code: int, path: str, request_id: str, error_messa
|
|
|
115
115
|
"status_code": status_code,
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
# 1. Try user override
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return engine.render(template_name, data)
|
|
124
|
-
except Exception:
|
|
125
|
-
pass
|
|
118
|
+
# 1. Try user override (singleton engine with custom filters/globals)
|
|
119
|
+
try:
|
|
120
|
+
return get_frond().render(template_name, data)
|
|
121
|
+
except (FileNotFoundError, Exception):
|
|
122
|
+
pass
|
|
126
123
|
|
|
127
|
-
# 2. Try framework default
|
|
128
|
-
|
|
129
|
-
if
|
|
124
|
+
# 2. Try framework default (singleton, filters/globals synced)
|
|
125
|
+
fw_engine = get_framework_frond()
|
|
126
|
+
if fw_engine is not None:
|
|
130
127
|
try:
|
|
131
|
-
|
|
132
|
-
return engine.render(template_name, data)
|
|
128
|
+
return fw_engine.render(template_name, data)
|
|
133
129
|
except Exception:
|
|
134
130
|
pass
|
|
135
131
|
|
|
@@ -848,9 +844,8 @@ async def app(scope: dict, receive, send):
|
|
|
848
844
|
# Try serving a template file (e.g. /hello -> src/templates/hello.twig or hello.html)
|
|
849
845
|
tpl_file = _resolve_template(request.path)
|
|
850
846
|
if tpl_file:
|
|
851
|
-
from tina4_python.
|
|
852
|
-
|
|
853
|
-
html = frond.render(tpl_file, {})
|
|
847
|
+
from tina4_python.core.response import get_frond
|
|
848
|
+
html = get_frond().render(tpl_file, {})
|
|
854
849
|
response.html(html)
|
|
855
850
|
elif request.path == "/":
|
|
856
851
|
response.html(_render_landing_page())
|
|
@@ -203,9 +203,8 @@ class Messenger:
|
|
|
203
203
|
**kwargs: Passed to send() (cc, bcc, attachments, etc.)
|
|
204
204
|
"""
|
|
205
205
|
try:
|
|
206
|
-
from tina4_python.
|
|
207
|
-
|
|
208
|
-
body = engine.render_string(template, data or {})
|
|
206
|
+
from tina4_python.core.response import get_frond
|
|
207
|
+
body = get_frond().render_string(template, data or {})
|
|
209
208
|
except ImportError:
|
|
210
209
|
body = template
|
|
211
210
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/auth/src/routes/api/gallery_auth.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/gallery/templates/src/routes/gallery_page.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/templates/docker/distroless/Dockerfile
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/af/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/af/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/en/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/en/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/es/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/es/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/fr/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/fr/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/ja/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/ja/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/zh/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.9.2 → tina4_python-3.10.0}/tina4_python/translations/zh/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|