skrift 0.1.0a14__py3-none-any.whl → 0.1.0a16__py3-none-any.whl

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.
@@ -4,6 +4,28 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>{% block title %}{{ site_name() }}{% endblock %}</title>
7
+
8
+ {# SEO Meta Tags #}
9
+ {% block seo_meta %}
10
+ {% if seo_meta %}
11
+ {% if seo_meta.description %}<meta name="description" content="{{ seo_meta.description }}">{% endif %}
12
+ {% if seo_meta.robots %}<meta name="robots" content="{{ seo_meta.robots }}">{% endif %}
13
+ <link rel="canonical" href="{{ seo_meta.canonical_url }}">
14
+ {% endif %}
15
+ {% endblock %}
16
+
17
+ {# OpenGraph Tags #}
18
+ {% block og_meta %}
19
+ {% if og_meta %}
20
+ <meta property="og:title" content="{{ og_meta.title }}">
21
+ {% if og_meta.description %}<meta property="og:description" content="{{ og_meta.description }}">{% endif %}
22
+ {% if og_meta.image %}<meta property="og:image" content="{{ og_meta.image }}">{% endif %}
23
+ <meta property="og:url" content="{{ og_meta.url }}">
24
+ <meta property="og:site_name" content="{{ og_meta.site_name }}">
25
+ <meta property="og:type" content="{{ og_meta.type }}">
26
+ {% endif %}
27
+ {% endblock %}
28
+
7
29
  <link rel="preconnect" href="https://fonts.googleapis.com">
8
30
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
31
  <link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@500;600&family=Lora:ital,wght@0,400;0,600;1,400;1,600&display=swap" rel="stylesheet">
@@ -33,10 +55,26 @@
33
55
  </header>
34
56
 
35
57
  <main class="container{% block main_class %}{% endblock %}">
36
- {% if flash %}
37
- <div class="flash-messages">
38
- <article role="alert">{{ flash }}</article>
39
- </div>
58
+ {# Enhanced flash messages with types #}
59
+ {% if flash_messages %}
60
+ <div class="flash-messages" role="status" aria-live="polite">
61
+ {% for msg in flash_messages %}
62
+ <article role="alert" class="flash flash-{{ msg.type.value }}" {% if msg.dismissible %}data-dismissible{% endif %}>
63
+ <span class="flash-message">{{ msg.message }}</span>
64
+ {% if msg.dismissible %}
65
+ <button type="button" class="flash-dismiss" aria-label="Dismiss">&times;</button>
66
+ {% endif %}
67
+ </article>
68
+ {% endfor %}
69
+ </div>
70
+ {# Backwards compatibility: old single flash string #}
71
+ {% elif flash %}
72
+ <div class="flash-messages" role="status" aria-live="polite">
73
+ <article role="alert" class="flash flash-info" data-dismissible>
74
+ <span class="flash-message">{{ flash }}</span>
75
+ <button type="button" class="flash-dismiss" aria-label="Dismiss">&times;</button>
76
+ </article>
77
+ </div>
40
78
  {% endif %}
41
79
 
42
80
  {% block content %}{% endblock %}
@@ -48,5 +86,21 @@
48
86
  </footer>
49
87
 
50
88
  {% block scripts %}{% endblock %}
89
+
90
+ <script>
91
+ // Flash message dismissal
92
+ document.querySelectorAll('.flash-dismiss').forEach(btn => {
93
+ btn.addEventListener('click', () => {
94
+ btn.closest('.flash').remove();
95
+ });
96
+ });
97
+ // Auto-dismiss success messages after 5 seconds
98
+ document.querySelectorAll('.flash-success[data-dismissible]').forEach(flash => {
99
+ setTimeout(() => {
100
+ flash.style.opacity = '0';
101
+ setTimeout(() => flash.remove(), 300);
102
+ }, 5000);
103
+ });
104
+ </script>
51
105
  </body>
52
106
  </html>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: skrift
3
- Version: 0.1.0a14
3
+ Version: 0.1.0a16
4
4
  Summary: A lightweight async Python CMS for crafting modern websites
5
5
  Requires-Python: >=3.13
6
6
  Requires-Dist: advanced-alchemy>=0.26.0
@@ -35,6 +35,11 @@ A modern Litestar-powered content management framework with multi-provider OAuth
35
35
  - **Dynamic Controllers**: Load controllers from `app.yaml` configuration
36
36
  - **SQLAlchemy Integration**: Async database support with SQLite/PostgreSQL
37
37
  - **Client-Side Sessions**: Encrypted cookie sessions for horizontal scalability
38
+ - **Hook/Filter System**: WordPress-like extensibility with async support
39
+ - **SEO Metadata**: Built-in meta descriptions, OpenGraph tags, and robots directives
40
+ - **Content Scheduling**: Schedule pages to publish at a future date
41
+ - **Page Revisions**: Automatic content history with restore capability
42
+ - **Sitemap & Robots.txt**: Auto-generated with filter extensibility
38
43
 
39
44
  ## Quick Start
40
45
 
@@ -121,11 +126,17 @@ skrift/
121
126
  ├── skrift/ # Main Python package
122
127
  │ ├── asgi.py # Application factory
123
128
  │ ├── config.py # Settings management
124
- │ ├── controllers/ # Route handlers
129
+ │ ├── controllers/ # Route handlers (auth, web, sitemap)
125
130
  │ ├── admin/ # Admin panel
126
131
  │ ├── auth/ # RBAC and guards
127
132
  │ ├── db/ # Models and services
128
- │ ├── lib/ # Template resolver
133
+ ├── models/ # Page, User, Role, PageRevision
134
+ │ │ └── services/ # page_service, revision_service
135
+ │ ├── lib/ # Core utilities
136
+ │ │ ├── hooks.py # Hook/filter system
137
+ │ │ ├── seo.py # SEO metadata utilities
138
+ │ │ ├── flash.py # Enhanced flash messages
139
+ │ │ └── template.py # Template resolver
129
140
  │ └── setup/ # Setup wizard
130
141
  ├── templates/ # Jinja2 templates
131
142
  ├── static/ # Static assets
@@ -2,10 +2,10 @@ skrift/__init__.py,sha256=eXE5PFVkJpH5XsV_ZlrTIeFPUPrmcHYAj4GpRS3R5PY,29
2
2
  skrift/__main__.py,sha256=wt6JZL9nBhKU36vdyurhOEtWy7w3C9zohyy24PLcKho,164
3
3
  skrift/alembic.ini,sha256=mYguI6CbMCTyfHctsGiTyf9Z5gv21FdeI3qtfgOHO3A,1815
4
4
  skrift/asgi.py,sha256=7uPvgsGMpZJyPOjIGxL9QlXTRLWh9uRAhcg-RdBS1c8,23355
5
- skrift/cli.py,sha256=aT-7pXvOuuZC-Eypx1h-xCiqaBKhIFjSqd5Ky_dHna0,4214
5
+ skrift/cli.py,sha256=-K-uO1r8y5r8wsRGygZFyaH1DsY1s9L0XViScPBnt9s,5744
6
6
  skrift/config.py,sha256=ZDOrYgp6gC6fE1nEZgrAOouoykhRo2NZo5U1-WLdDSc,7862
7
7
  skrift/admin/__init__.py,sha256=x81Cj_ilVmv6slaMl16HHyT_AgrnLxKEWkS0RPa4V9s,289
8
- skrift/admin/controller.py,sha256=5ZDypvKHXLNDESsKNsdsH2E3Si5OqlpzttFl7Ot8aF0,15651
8
+ skrift/admin/controller.py,sha256=gSprerjhxqxaH2lHm8vbLuz-jslN553FpbKF7jwEm9Y,19607
9
9
  skrift/admin/navigation.py,sha256=VwttFoIUIJy5rONKIkJd5w4CNkUpeK22_OfLGHecN34,3382
10
10
  skrift/alembic/env.py,sha256=GaQx7D-3f0zVTV4YJNhN0GOfqHL99N4VBfMzjZJz0Bc,2673
11
11
  skrift/alembic/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9NFvDgl93dMj8,635
@@ -16,28 +16,42 @@ skrift/alembic/versions/20260122_175637_a9c55348eae7_remove_page_type_column.py,
16
16
  skrift/alembic/versions/20260122_200000_add_settings_table.py,sha256=aG4pxp18fwonGAWt7EoT0XaiIEmu7zltSrj8e2a8QZU,1310
17
17
  skrift/alembic/versions/20260129_add_oauth_accounts.py,sha256=KPuzJ5J13FEbSbyziuB-nfO67i4cRgBeQnygn-uNQx8,5412
18
18
  skrift/alembic/versions/20260129_add_provider_metadata.py,sha256=prDfnYM0cODBSYb9xYqW5Dab2WDjHNkkEMRH-hI7BIA,846
19
+ skrift/alembic/versions/20260202_add_content_scheduling.py,sha256=b5eTIzVmHO5x9UJDwwqQG1gLDNxTzxY0qIl0xTkgZA4,1079
20
+ skrift/alembic/versions/20260202_add_page_ordering.py,sha256=4MdupLfmaM0oftbmRMGOUIDrT55yFCqQ8v9uCOofOZQ,941
21
+ skrift/alembic/versions/20260202_add_page_revisions.py,sha256=LKmxerftfWguGbIjveemnm9nEZ9ZjTm5rdEwoRiUVBY,2179
22
+ skrift/alembic/versions/20260202_add_seo_fields.py,sha256=rLnRY1RyckoVno6miUlTtgv_IceIFJRj3OS7aUVXcKE,1546
19
23
  skrift/auth/__init__.py,sha256=uHMqty3dgDSYlReVT96WhygzH6qNAWSVDWoxumzxmsA,1155
20
24
  skrift/auth/guards.py,sha256=QePajHsGnJ4R_hlhzblr5IoAgZcY5jzeZ64bJwDL9hM,4451
21
25
  skrift/auth/roles.py,sha256=Cvwv8v7Li6CJHhucTuzxRjaNmS530F9sbbQlCPRqhm4,3291
22
26
  skrift/auth/services.py,sha256=h6GTXdN5UMRYglnaFz4asMoutVkSSAyL3_Vt56N26pA,5441
27
+ skrift/claude_skill/SKILL.md,sha256=cOEBAsUSw224op9XagsRGpv1rMBswD23ZhfsPgETLOs,5972
28
+ skrift/claude_skill/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ skrift/claude_skill/architecture.md,sha256=jKtegv3FsWmeWsW0bmRr6tQMVlbFt-y_wSTRVn90qtc,8508
30
+ skrift/claude_skill/patterns.md,sha256=YjbBgozeUpDYx44PazDXY8r6bTWddvUiZ7ub6Ol7qtc,14415
23
31
  skrift/controllers/__init__.py,sha256=bVr0tsSGz7jBi002Lqd1AA1FQd7ZA_IagsqTKpiHiK0,147
24
32
  skrift/controllers/auth.py,sha256=ohYjBJiRa5RDQKUQjL3nR6lzm4uUZcfIgnF2G-QY5o8,21905
25
- skrift/controllers/web.py,sha256=vmoBS1u5G9gCBu65S49yqZn_WBKlmsqlcvX5tYXTKnE,2348
33
+ skrift/controllers/sitemap.py,sha256=Yfz2ElHrkZVMhAN5ixriU5RwEFJ713rS0Uezj90Bfts,3814
34
+ skrift/controllers/web.py,sha256=J-kbmzwJcKfiBvNbF8yR7GHGo0jhvWzY77YstJi_pcI,2968
26
35
  skrift/db/__init__.py,sha256=uSghyDFT2K4SFiEqUzdjCGzWpS-Oy6Sd1FUappau-v0,52
27
36
  skrift/db/base.py,sha256=QJplFj9235kZdScASEpvyNHln6YW2hqbHwJEYZ3OSsc,173
28
- skrift/db/models/__init__.py,sha256=wFF9YWe7rhIWIzRuMtAWVDcZdJsNcKnjfhKbLZw9JVs,341
37
+ skrift/db/models/__init__.py,sha256=DtgYPLs8rTLNFmZ0-HzD_8uhvaGRtayZCrxpMhAo88U,413
29
38
  skrift/db/models/oauth_account.py,sha256=fzmApdtrRYeEWLl35Y7H0YtF7CWjzrpG-lknBOuYRc8,1840
30
- skrift/db/models/page.py,sha256=CI5W2sWq0zbKHxfwH5TpmGdJ4zlTicckzpdZtaqjJVE,1019
39
+ skrift/db/models/page.py,sha256=pYMWBmQ7FfDiFcyBU3xV4kbpWboimZw5TZtVDOcr73o,2068
40
+ skrift/db/models/page_revision.py,sha256=S2TO8hR5ThPFRk1Ovdn3lFau6D2H6TLhfFX6ekp_OTI,1399
31
41
  skrift/db/models/role.py,sha256=VkwkF3XWemmFtkUpQRk6RTIBfcukrU-0PUPCeo8x834,1768
32
42
  skrift/db/models/setting.py,sha256=Am4HTyq2LFR408R6BZb--slys1xM8YLYq9HTq_gybD0,392
33
43
  skrift/db/models/user.py,sha256=kkR3h0CphUyvOGJOpiZH6Qp28LqW2OriwVTfybs7vuY,1338
34
44
  skrift/db/services/__init__.py,sha256=qAC24IPOYg6AampUWonmLeajljQRMwUw0lgXksQG6Nk,69
35
45
  skrift/db/services/oauth_service.py,sha256=1065tYGvrSer0X28GblibrSz2BjwVjl3tndXk1plthE,5208
36
- skrift/db/services/page_service.py,sha256=cXJ-urV7LjUDoVsT1P52f6wcOsur3T-pvqKkGG4xlvI,5246
37
- skrift/db/services/setting_service.py,sha256=eqFxukn8QFrDHQbaBILOLjP1nr34JPIPFT_NnhmeaTY,5613
38
- skrift/lib/__init__.py,sha256=Ew53SFcJcoohNF_FEDoDXsrks9cKZQonoaJAWyjXWMs,132
46
+ skrift/db/services/page_service.py,sha256=vVuxy7rNC9J6iCGFtmnt7Jrgo3cFm-vscdWcZ2RuMOQ,9830
47
+ skrift/db/services/revision_service.py,sha256=YBHeSac6V2_K3AKzDqup8fg0nys9nVLGOnLYD7GkxUQ,3701
48
+ skrift/db/services/setting_service.py,sha256=9u8LUMxnZAeSxf98_8GZXi5uioT4Jz-rYdIbs6wa4KE,5869
49
+ skrift/lib/__init__.py,sha256=XodsWJweaIpHtVkAHkEZHcCY8NSOBrUWxUQGZidP9l0,359
39
50
  skrift/lib/exceptions.py,sha256=p8ceLIQCc7agCwW6-mhBDAuMAMxZDcf9TDLC6PfztU4,5803
51
+ skrift/lib/flash.py,sha256=nWX7H8s218oBOE4d9kE6asHG_TNM4BbWJ7qrN65-Ewc,2921
52
+ skrift/lib/hooks.py,sha256=HsrOM-mVZSd1mSlNsj8YpfjJ7HwufDjFSnVUenmnwjA,8710
40
53
  skrift/lib/markdown.py,sha256=fPLUIAsmFXC64Os2RngQG7P2xRKBd1RO8fh7b5_gV1U,950
54
+ skrift/lib/seo.py,sha256=3fAfXn_7Jpq_OhINpcbQznixLcJTbaD-I86_Je2SFoo,2512
41
55
  skrift/lib/template.py,sha256=4_urkRfvth75yNeQ5TyGTHvkvs3vVef7TcwZx0k285k,4226
42
56
  skrift/setup/__init__.py,sha256=3VjFPMES5y0M5cQ9R4C1xazqiEPEDqTPjX9-3rBMXnA,478
43
57
  skrift/setup/config_writer.py,sha256=YFH3FVjXN7Rum2fzGVPAQRkjdc9b0bHECDqMKYiEkhg,6347
@@ -45,8 +59,8 @@ skrift/setup/controller.py,sha256=v0Ey8T7ptJ5A3vOqQ1TUAXH1bQwA0288J5uyUWMihsw,34
45
59
  skrift/setup/middleware.py,sha256=Nai8ZG2vHldngmAhq7kWzAwKRNcP5tHKhJHa5dCh404,2941
46
60
  skrift/setup/providers.py,sha256=0BFKB6168NcmtXxFF6ofHgEDMQD2FbXkexsqrARVtDI,7967
47
61
  skrift/setup/state.py,sha256=RMe9LtIjzDoOm9u-Nk5-KAnr_JBiQIjWDpTP9E30ezc,9304
48
- skrift/static/css/style.css,sha256=-Ijp4PCugWzhHhtZTaRUAITHJDW-0AsbNpDCFI1njVQ,20943
49
- skrift/templates/base.html,sha256=4bg4s4VdES0dSvhJYLgrfrN26ynqeq1-3jyKPkWWVWk,2065
62
+ skrift/static/css/style.css,sha256=6in8KjmwythfQV9pGt-uSCJCoHG1OijrdDOOad7oYBk,22978
63
+ skrift/templates/base.html,sha256=s6gylukPyBvb9StgNz8MRZr4h3QT3C8GTMiwOu23nC0,4421
50
64
  skrift/templates/error-404.html,sha256=sJrDaF3Or3Nyki8mxo3wBxLLzgy4wkB9p9wdS8pRA6k,409
51
65
  skrift/templates/error-500.html,sha256=MR0wJ1JKLqdmdvsoJbQnZxLkxDPE59LrlbtVPKLM8-A,401
52
66
  skrift/templates/error.html,sha256=tg45Hj0wNc9QiZKBVVQ2WsqDiAkByXZnuehTdJPclXc,415
@@ -54,8 +68,9 @@ skrift/templates/index.html,sha256=lzZlnoZ2luY__OtRVa61mpQIgcopAbkKa2rS9XRfRlI,1
54
68
  skrift/templates/page.html,sha256=aSTypibx86SzIhO7GTff8XXVrW8D-XbHNaTo_UT31oc,770
55
69
  skrift/templates/admin/admin.html,sha256=8sErpGKedl7Hf_CMeu53bUEHptH1FqdBX9LT3z-1HcU,454
56
70
  skrift/templates/admin/base.html,sha256=JX1MPw9XTY8jCT2M6iHUwEj8NPNOdZPca2cDUEs9kfQ,659
57
- skrift/templates/admin/pages/edit.html,sha256=s-uZ4BYG7BdnWYTBSS1mr5aFL8XfT8h-KNiSIraWmHw,1322
58
- skrift/templates/admin/pages/list.html,sha256=LYh1vEwSHkyXihjcy5PIo33iA7UeIxprw4Gsn1WZMm4,2185
71
+ skrift/templates/admin/pages/edit.html,sha256=WqA1xYg5ZbDmH77wuu-8pvxsQ0scS6QpYXlzrLKxAj8,3859
72
+ skrift/templates/admin/pages/list.html,sha256=KHjqIQMNV1Ts6Fgx9p_waiGOb9lVcAgLCMmomKAQoeA,2602
73
+ skrift/templates/admin/pages/revisions.html,sha256=hthxdcKqz_DUHzky_5dn6cDEsZWR49W2sqKTiJjhVpA,2075
59
74
  skrift/templates/admin/settings/site.html,sha256=xHZCZGj9XqyLKCe2eoBlpI3oFIx5VoG_5FP-VAF2mz4,1516
60
75
  skrift/templates/admin/users/list.html,sha256=9GWql1la5Srm-OOgooHR9Eouk7ZL66K_FXY6HAAB5lA,1732
61
76
  skrift/templates/admin/users/roles.html,sha256=pos-ZM-gXYCN_D8DZpzwEBEm_WvmOKMMPz-3xJqs7nY,1473
@@ -69,7 +84,7 @@ skrift/templates/setup/configuring.html,sha256=2KHW9h2BrJgL_kO5IizbAYs4pnFLyRf76
69
84
  skrift/templates/setup/database.html,sha256=gU4-315-QraHa2Eq4Fh3b55QpOM2CkJzh27_Yz13frA,5495
70
85
  skrift/templates/setup/restart.html,sha256=GHg31F_e2uLFhWUzJoalk0Y0oYLqsFWyZXWKX3mblbY,1355
71
86
  skrift/templates/setup/site.html,sha256=PSOH-q1-ZBl47iSW9-Ad6lEfJn_fzdGD3Pk4vb3xgK4,1680
72
- skrift-0.1.0a14.dist-info/METADATA,sha256=unD0pS4u31RZprH6rOeGVZJ_zA565aw7wTFxXzG91Go,6511
73
- skrift-0.1.0a14.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
74
- skrift-0.1.0a14.dist-info/entry_points.txt,sha256=uquZ5Mumqr0xwYTpTcNiJtFSITGfF6_QCCy2DZJSZig,42
75
- skrift-0.1.0a14.dist-info/RECORD,,
87
+ skrift-0.1.0a16.dist-info/METADATA,sha256=aS6GVqS-9stFAZ_wRa86gOZHVfr21BRUTi91wae8Vqo,7267
88
+ skrift-0.1.0a16.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
89
+ skrift-0.1.0a16.dist-info/entry_points.txt,sha256=uquZ5Mumqr0xwYTpTcNiJtFSITGfF6_QCCy2DZJSZig,42
90
+ skrift-0.1.0a16.dist-info/RECORD,,