الوثائقأطر عمل Fullstack
من Astro إلى النكسي
صفحة Nexy .nexy هي صفحة Astro تحتوي على Python في الجزء الأمامي --- بدلاً من TypeScript: نفس HTML الخاص بالخادم الأول، ونفس الجزر وتوجيهات client:*، التي يتم تقديمها عند كل طلب.
كل قسم أدناه يوضح عادة Astro، ثم نفس الشيء في Nexy.
صفحة
const title = "About";<h1>{title}</h1>الواجهة هي Python والقالب هو Jinja2:
title = "About"<h1>{{ title }}</h1>src/pages/ هو src/routes/، و index.astro هو index.nexy.
الحلقات والشروط
const users = [{ name: "Ada", admin: true }, { name: "Alan", admin: false }];<ul> {users.map((user) => <li>{user.name}{user.admin && <strong> admin</strong>}</li>)}</ul>users = [{"name": "Ada", "admin": True}, {"name": "Alan", "admin": False}]<ul> {% for user in users %} <li>{{ user.name }}{% if user.admin %}<strong> admin</strong>{% endif %}</li> {% endfor %}</ul>المكونات و Astro.props
const { title, tone = "neutral" } = Astro.props;<article class={`card card-${tone}`}> <h2>{title}</h2> <slot /></article>يتم الإعلان عن الخاصيات باستخدام prop[...]، والافتراضي هو Python الافتراضي، و <slot /> هو <Slot />:
title: prop[str]tone: prop[str] = "neutral"<article class="card card-{{ tone }}"> <h2>{{ title }}</h2> <Slot /></article>from "@/components/Card.nexy" import Card<Card title="Latest" tone="warm"> <p>This week</p></Card>@ هو src/: nx new يكتب useAliases = {"@": "src"} في nexyconfig.py.
التخطيطات
const { title } = Astro.props;<html> <head><title>{title}</title></head> <body><slot /></body></html>import Base from "../layouts/Base.astro";<Base title="About"><h1>About</h1></Base>الصفحة لا تستورد تخطيطها: أقرب layout.nexy فوقها يغلفها، والجذر يملك الوثيقة.
from nexy import useMetadata children: prop[NexyElement]<!DOCTYPE html><html> <head>{{ useMetadata().html() }}</head> <body>{{ children | safe }}</body></html>العنوان والعلامات الوصفية
تصبح الدعامة title للتخطيط metadata في الصفحة، والتي يكتبها useMetadata().html() في <head> للتخطيط أعلاه:
metadata = {"title": "Blog", "description": "Posts about Nexy"}<h1>Blog</h1>المسارات الديناميكية و getStaticPaths
export function getStaticPaths() { return [ { params: { slug: "hello" }, props: { title: "Hello" } }, { params: { slug: "world" }, props: { title: "World" } }, ];}const { title } = Astro.props;<h1>{title}</h1>يتم عرض صفحة .nexy ديناميكية عند الطلب، لذلك لا توجد قائمة بالمسارات: المقطع هو دعامة، والجزء غير المعروف هو 404.
from nexy import notFound POSTS = {"hello": "Hello", "world": "World"} slug: prop[str]if slug not in POSTS: notFound()title = POSTS[slug]<h1>{{ title }}</h1>[...path].astro هو [...path].nexy.
الجزر و client:*
import Counter from "../components/Counter.tsx";<h1>Static heading</h1><Counter start={3} client:visible />يصبح التوجيه سمة directive بنفس القيم:
from "@/components/Counter.tsx" import Counter<h1>Static heading</h1><Counter start=3 directive="client:visible" />| Astro | نكسي |
|---|---|
client:load |
directive="client:load"، أو بدون توجيه |
client:idle |
directive="client:idle" |
client:visible |
directive="client:visible" |
client:media="(min-width: 768px)" |
directive="client:media" media="(min-width: 768px)" |
client:only="react" |
مقبول، ولكن لا يرطب أبدًا: استخدم client:load |
يتم تعيين إطار العمل مرة واحدة في nexyconfig.py، ويستخدم المشروع واحدًا:
from nexy.core.models import NexyConfigModelfrom nexy.frontend import react class NexyConfig(NexyConfigModel): useFF = react() useAliases = {"@": "src"}Markdown صفحة
---layout: ../layouts/Base.astro---# Changelogالملف .md ضمن src/routes/ هو صفحة ملفوفة بأقرب تخطيط بدون مفتاح layout::
# Changelog Version 2.2 is out..mdx تعمل الصفحات أيضًا، مع React أو Preact كإطار عمل. انظر Markdown و MDX.
نقاط نهاية API
export function GET({ params }) { return Response.json({ id: Number(params.id) });}async def GET(id: int): return {"id": id}الجسم هو نموذج Pydantic، يتم التحقق من صحته قبل تشغيل الوظيفة:
from pydantic import BaseModel from nexy.http import JSONResponse class NewItem(BaseModel): name: str async def POST(item: NewItem): return JSONResponse({"created": item.name}, status_code=201)Astro.redirect و Astro.cookies و Astro.url
const theme = Astro.cookies.get("theme")?.value ?? "light";if (!Astro.cookies.has("session")) return Astro.redirect("/login");const page = Astro.url.searchParams.get("page") ?? "1";<p>{theme} theme, page {page}</p>نفس القراءات عبارة عن خطافات، وإعادة التوجيه هي وظيفة:
from nexy import redirect, useCookies, useSearchParams cookies = useCookies()if "session" not in cookies: redirect("/login")theme = cookies.get("theme", "light")page = useSearchParams().get("page", "1")<p>{{ theme }} theme, page {{ page }}</p>الوسيطة
export function onRequest(context, next) { return next().then((response) => { response.headers.set("x-app", "demo"); return response; });}from nexy.http import Request async def middleware(request: Request, call_next): response = await call_next(request) response.headers["x-app"] = "demo" return responseيقوم middleware.py الموجود في المجلد الفرعي بتغليف المسارات الموجودة أسفله فقط، مما يحل محل عمليات التحقق من المسار داخل onRequest.
Astro الأفعال
import { defineAction } from "astro:actions";import { z } from "astro:schema"; export const server = { addNote: defineAction({ accept: "form", input: z.object({ title: z.string() }), handler: async ({ title }) => ({ title }), }),};import { actions } from "astro:actions";<form method="POST" action={actions.addNote}> <input name="title" /> <button>Add</button></form>الفعل هو دالة Python في src/actions/؛ نموذج ينشر في مساره:
from nexy.decorators import Action NOTES: list[str] = [] @Actionasync def add_note(title: str) -> None: NOTES.append(title)from src.actions.notes import NOTES<form method="post" action="{{ __actions_path['add_note'] }}"> <input name="title"> <button type="submit">Add</button></form><ul> {% for note in NOTES %} <li>{{ note }}</li> {% endfor %}</ul>من جزيرة، useAction(add_note) في @nexy/client يستدعي نفس الوظيفة مع الإدخال المكتوب.
<Image />
import { Image } from "astro:assets";import logo from "../assets/logo.png";<Image src={logo} alt="Logo" width={128} height={32} />
from nexy import Image<Image src="/logo.png" alt="Logo" width=128 height=32 />404.astro
<h1>Not found</h1><h1>Not found</h1>لا يزال عملاء API يحصلون على {"detail": "Not Found"}.
الإخراج الثابت والعرض عند الطلب
Astro ينشئ HTML ثابتًا بشكل افتراضي ويتم عرضه عند الطلب باستخدام output: "server" أو export const prerender = false. يعرض Nexy كل صفحة عند الطلب، ويخزن مؤقتًا الصفحات التي تختارها لكل عنوان URL:
revalidate = 60<h1>News</h1>لا يوجد تصدير ثابت: nx start يخدم الموقع. انظر التقديم.
الجري
| Astro | نكسي |
|---|---|
npm create astro@latest |
nx new |
astro dev |
nx dev |
astro build و astro preview |
nx build، ثم nx start |
public/ |
public/، خدم في / |
astro add react |
nx new مع إطار، أو useFF = react() |