diff --git a/README.md b/README.md index fcdfcd2..a0ed6b6 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ | **آدرسِ زنده** | `https://api.math.tadrisino2.ir` · [سلامت](https://api.math.tadrisino2.ir/api/health) | | **استک** | Python 3.11+ · Django 5.2 · DRF · SQLite · Qdrant (RAG) | | **API** | ۵۶ اندپوینت · مستنداتِ زنده در `/api/docs/` | -| **تست** | ۴۸۱ تست، همه سبز (`python manage.py test`) | +| **تست** | ۴۸۳ تست، همه سبز (`python manage.py test`) | | **محتوا** | ۸ پایه · ۵۸ فصل · ۲۶۳ نود · ۲٬۶۱۷ درس · ۲٬۴۶۳ سوال | --- diff --git a/config/settings.py b/config/settings.py index a9648fb..7526e61 100644 --- a/config/settings.py +++ b/config/settings.py @@ -237,7 +237,9 @@ ROOT_URLCONF = 'config.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], + # قالب‌های سطحِ پروژه (که به هیچ اپی تعلق ندارند) — فعلاً فقط + # پوسته‌ی راست‌به‌چپِ صفحه‌های مستنداتِ API. + 'DIRS': [BASE_DIR / 'templates'], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ diff --git a/config/tests.py b/config/tests.py index 083a296..4e73c87 100644 --- a/config/tests.py +++ b/config/tests.py @@ -450,3 +450,27 @@ class CorsDevPortTests(TestCase): # و پذیرشِ هر پورتِ localhost را واقعاً خطرناک می‌کرد. from django.conf import settings self.assertFalse(settings.CORS_ALLOW_CREDENTIALS) + + +class ApiDocsRtlShellTests(TestCase): + """ + صفحه‌های مستنداتِ API باید پوسته‌ی راست‌به‌چپِ خودمان را داشته باشند. + + بدونِ آن، Swagger متنِ فارسی را در یک بلوکِ چپ‌به‌راست می‌چیند و نتیجه‌اش + پریدنِ نقطه‌ی جمله به ابتدای خط و برعکس شدنِ ستون‌های جدول است. این تست + هست چون خرابی‌اش فقط با چشم دیده می‌شود: هیچ خطایی نمی‌دهد و هیچ تستِ + دیگری نمی‌گیردش. + """ + + def test_swagger_ui_carries_the_rtl_shell(self): + html = self.client.get('/api/docs/').content.decode() + self.assertIn('direction: rtl', html) + # کد باید صریحاً چپ‌به‌راست بماند، وگرنه «Authorization: Bearer ...» + # در بلوکِ RTL جابه‌جا می‌شود. + self.assertIn('direction: ltr', html) + # قالبِ اصلیِ drf-spectacular باید دست‌نخورده زیرش باشد. + self.assertIn('swagger-ui-bundle', html) + + def test_redoc_carries_the_rtl_shell(self): + html = self.client.get('/api/redoc/').content.decode() + self.assertIn('direction: rtl', html) diff --git a/config/urls.py b/config/urls.py index 5d78161..569e0b3 100644 --- a/config/urls.py +++ b/config/urls.py @@ -68,8 +68,13 @@ urlpatterns = [ # OpenAPI schema + Swagger UI + Redoc path('api/schema/', SpectacularAPIView.as_view(), name='schema'), - path('api/docs/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), - path('api/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), + # قالبِ خودمان فقط یک پوسته‌ی راست‌به‌چپ روی قالبِ drf-spectacular است؛ + # بدونش متنِ فارسی در یک بلوکِ LTR رندر می‌شود و نقطه‌ی جمله و ترتیبِ + # ستون‌های جدول جابه‌جا می‌شوند. توضیح در خودِ قالب. + path('api/docs/', SpectacularSwaggerView.as_view( + url_name='schema', template_name='tadrisino/swagger_ui.html'), name='swagger-ui'), + path('api/redoc/', SpectacularRedocView.as_view( + url_name='schema', template_name='tadrisino/redoc.html'), name='redoc'), # همه زیرِ /api/ جمع می‌شوند؛ هر اپ مسیرهای خودش را نگه می‌دارد، پس # ترتیبِ این فهرست اهمیتی ندارد و تداخلی بینشان نیست. diff --git a/templates/tadrisino/redoc.html b/templates/tadrisino/redoc.html new file mode 100644 index 0000000..39198ee --- /dev/null +++ b/templates/tadrisino/redoc.html @@ -0,0 +1,36 @@ +{% extends "drf_spectacular/redoc.html" %} + +{# همان مشکلِ راست‌به‌چپِ swagger_ui.html، این بار در Redoc. توضیحِ کامل آنجاست. #} + +{% block head %} +{{ block.super }} + +{% endblock head %} diff --git a/templates/tadrisino/swagger_ui.html b/templates/tadrisino/swagger_ui.html new file mode 100644 index 0000000..a392afb --- /dev/null +++ b/templates/tadrisino/swagger_ui.html @@ -0,0 +1,69 @@ +{% extends "drf_spectacular/swagger_ui.html" %} + +{# Swagger UI هر متنی را چپ‌به‌راست می‌چیند، چون برای انگلیسی نوشته شده. متنِ + ما فارسی است، و در یک بلوکِ LTR نتیجه‌اش این می‌شود که نقطه‌ی پایانِ جمله + به ابتدای خط می‌پرد، ترتیبِ ستون‌های جدول برعکس می‌شود، و هر کلمه‌ی + انگلیسیِ وسطِ جمله جای خودش را گم می‌کند. + + راهِ حل، تغییرِ *متن* نیست — جهتِ خودِ بلوک باید راست‌به‌چپ شود. اینجا فقط + بخش‌هایی که Markdown فارسی رندر می‌کنند RTL می‌شوند؛ ساختارِ خودِ Swagger + (مسیرها، متدها، نامِ فیلدها) دست‌نخورده می‌ماند چون همه انگلیسی‌اند. + + قالبِ اصلی دست نمی‌خورد: این فایل با {{ block.super }} رویش سوار می‌شود، + پس به‌روزرسانیِ drf-spectacular چیزی را خراب نمی‌کند. #} + +{% block head %} +{{ block.super }} + +{% endblock head %}