ניתוב וכתובות ידידותיות
כתובות רגילות ו-Regex מטבלת seoUrl, הפניות 301, קונטרולרי מערכת, שמירת פרמטרי קמפיין ו-503 חכם כשה-DB נופל במקום 404 שמוחק אתכם מגוגל.
ליבת PHP אחת שמריצה מאות אתרים ומערכות בעברית: פאנל ניהול מובנה, מנוע טפסים וטבלאות, מטמון עמודים מלא, SEO, שרת MCP וסוכני AI. ועכשיו גם תיעוד שלם ותקן קוד אחיד, כדי שכל מפתח יוכל להיכנס, להבין ולבנות.
<?php
// /news → index() /news/item/12 → item() with $_GET["id"] = 12
class news extends wz_controller
{
function index()
{
$items = DB::query("news", ["active" => "1"], "created DESC", "", 20)->get_all();
return $this->view("news/list", ["items" => $items]);
}
function item()
{
$row = DB::get_val("news", (int)$_GET["id"]);
if (!$row) return "ERRORPAGE"; // → the site's 404 page
SEO::set_var("title", $row["title"]); // <title> + og:title
PAGE::$cache_this_page = true; // full-page cache (gzip)
return $this->view("news/item", ["row" => $row]);
}
}
<?php
// {admin}/News → index() {admin}/News/insert/12 → insert()
class ADMINMODULE_News extends bgl_controller
{
function index()
{
$tbl = new panel_table("news");
$tbl->title = "חדשות";
$tbl->query = DB::query("news", null, "id DESC");
$tbl->titles = [
["title" => "כותרת", "field" => "title", "editable" => true],
["title" => "פעיל", "field" => "active", "type" => "boolean", "editable" => true],
];
$tbl->btn_add_url = CONFIG::$admin_url . "/News/insert";
$tbl->delete = fn($id) => DB::delete("news", ["id" => $id]);
return $tbl->get_html();
}
function insert()
{
$frm = new AJAXForm("newsEdit");
$frm->table = "news";
if (isset($_GET["id"])) $frm->update_mode((int)$_GET["id"]);
$title = new FormInput_Text("title"); $title->title = "כותרת"; $title->Must();
$body = new FormInput_WZ_Editor("content"); $body->title = "תוכן";
$img = new FormInput_Image("image"); $img->title = "תמונה ראשית";
$on = new FormInput_Switch("active"); $on->title = "פעיל";
foreach ([$title, $body, $img, $on] as $inp) $frm->push($inp);
return $frm->IsFormSent() ? $frm->save() : $frm->get_html();
}
}
// POST https://your-site.co.il/system/mcp
// Authorization: Bearer <token issued by the Market's MCP product>
{
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "list_rows",
"arguments": { "panel": "News", "q": "תקציב", "pgnm": 1 }
}
}
// every call runs AS the admin who owns the token:
// group permissions, form validation and content tables apply
// exactly as if that admin clicked through the panel.
קוד אמיתי מתוך התיעוד. אותו דפוס בדיוק משמש את הפאנלים המובנים של הליבה.
כל יכולת בליבה נולדה מצורך של אתר אמיתי: עיתון עם אלפי כתבות ביום, חנות עם קמפיינים, מערכת ניהול פנימית. היום היא נפתחת למפתחים עם תיעוד ותקן.
כיוון הטקסט מגיע מטבלת הפלטפורמות, הפאנל כולו RTL, שדות, תאריכים ועורך התוכן מתנהגים נכון בעברית. אין "תמיכה ב-RTL", יש RTL.
רשימה היא אובייקט panel_table, טופס הוא Form עם שדות FormInput_*. כל פאנל הוא קובץ PHP אחד שגם AI יכול לקרוא ולהפעיל דרך MCP, בלי כפילות API.
כל אתר מגיע עם שרת MCP, טוקנים לכל מנהל, סוכנים עם אישורים וזיכרון, וצ'אט בתוך הפאנל. ההרשאות של המנהל הן ההרשאות של ה-AI, לא פחות ולא יותר.
כתובות רגילות ו-Regex מטבלת seoUrl, הפניות 301, קונטרולרי מערכת, שמירת פרמטרי קמפיין ו-503 חכם כשה-DB נופל במקום 404 שמוחק אתכם מגוגל.
עשרות סוגי שדות: טקסט, עורך תוכן, תמונות וגלריות, תאריכים, Select מה-DB, תגיות, JSON, Cron, SEO. ולידציה בשרת ובדפדפן, רב-לשוניות ושמירה אוטומטית לטבלה.
לכתוב טופס ←רשימה ממוינת עם חיפוש, עריכה בתוך הטבלה, פעולות קבוצתיות, סדר ידני בגרירה, ייצוא Excel וייבוא עם AI. Vue 3 מתחת למכסה, PHP אחד למעלה.
להגדיר רשימה ←העמוד נשמר כ-gzip ומוגש עוד לפני ש-PHP מתעורר, עם נעילת בנייה נגד הצפות, ניקוי פרמטרי מעקב, ופינוי אוטומטי של קבצים שפג תוקפם.
כללי המטמון ←העלאות עם בדיקת תוכן, תמונות ממוזערות לפי בקשה, חיתוך ועריכה בדפדפן, S3 או FTP מרוחק, ניקוי Cloudflare והמרה ל-WebP.
STORAGE API ←מנהל משימות עם לוגים לכל ריצה, קטגוריות כ-kill switch, תור דואר עם תבניות, ובדיקות בריאות של השרת ישר מהפאנל.
לרשום משימה ←ממצאים לפי עמוד, זיהוי קניבליזציה, IndexNow, אימות מול Search Console, GEO, ותגיות ו-Schema מתוך ה-API של העמוד.
חבילת ה-SEO ←בדיקה לפני ההחלפה (PHP, דיסק, DB, חתימת sha256), בדיקה אחרי עם core_ping וחזרה אחורה אוטומטית. ערוצי stable ו-dev.
הליבה (system/) לעולם לא נערכת באתר. האתר מוסיף קוד בתיקיית application/ ובערכת הנושא, והליבה טוענת אותו לפי מוסכמות ברורות. כך עדכון ליבה הוא החלפת תיקייה אחת.
CONFIG::preinit() ובודק אם זו ריצת CLI/Cron.CRM_platforms וקובע שפה, כיוון ו-URL בסיס.module, pname, id. אדמין, קונטרולרי מערכת, נכסים סטטיים ו-Regex.application/controllers/{module}.php, קורא למתודה, עוטף ב-wrapper().echo.הכל מתועד צעד-צעד, כולל מה לעשות כשמשהו לא נמצא: מחזור חיי בקשה, 404 ו-503, דיבוג ניתוב עם ?__router_trace=1.
my-site.co.il/ ├── index.php # require system/core.php ├── .htaccess # rewrite + page cache ├── application/ │ ├── includes/init.php # site bootstrap, hooks │ ├── admin/includes/mcp_tools.php # site MCP tools │ ├── controllers/ # /news → news.php │ ├── views/ # Smarty .tpl │ ├── admin/ # ADMINMODULE_News … │ └── models/ ├── themes/ │ └── default/ │ ├── index.php # TEMPLATE_default │ └── index.tpl # {$content} ├── system/ # = the core. never edit │ ├── core.php │ ├── collections/ controllers/ libraries/ │ ├── admin/ assets/ themes/ │ └── market_settings.json ├── storage/ # uploads └── cache/ # per-platform file cache
מבנה האתר המלא, מה חובה ומה אופציונלי, בדף מבנה התיקיות של אתר.
כל אתר WIZZO CMS חושף נקודת קצה MCP ב-/system/mcp. לקוח MCP (Claude, Cursor, או הסוכנים של WIZZO) מזדהה עם טוקן של מנהל, וכל קריאה לכלי רצה דרך אותם פאנלים, טפסים והרשאות שהמנהל היה עובר בלחיצה.
CRM_adminPanel_mcp_tokens עם תפוגה, רשימת כלים מותרים ו"שימוש אחרון". סוכנים מקבלים טוקני ריצה קצרי-חיים. קבוצת ההרשאות של המנהל היא הגבול של ה-AI.panel_table ו-Form חושפים סכמת JSON. הכלים הכלליים (panel_schema, list_rows, save_record, set_field, form_action) עובדים על כל פאנל שתכתבו, בלי שורת קוד נוספת.approve_writes), זוכר מה למד, ונעצר ב-kill switch אחד. כל ריצה מתועדת צעד-צעד.application/admin/includes/mcp_tools.php דרך AGENT_TOOLS::add_tool() הופך פונקציית PHP לכלי MCP עם סכמה, תיאור והרשאה. כך סוכן יכול "לסגור הזמנה" או "לפרסם מהדורה" בשפה של העסק שלכם.{
"mcpServers": {
"my-site": {
"type": "http",
"url": "https://my-site.co.il/system/mcp",
"headers": { "Authorization": "Bearer wz_…" }
}
}
}
list_panelspanel_schemalist_rowssave_recordset_fieldform_actiondelete_recordimport_mediasearch_medianotify_adminrememberrecall
הקטלוג המלא, סכמות הקלט ומודל ההרשאות: קטלוג כלי ה-MCP · כתיבת כלי לאתר · סוכני AI.
ה-Market מפעיל שירות, מוסר מפתח API, והליבה פותחת את הפאנל של המוצר בתפריט הניהול עם ההרשאות הרגילות. למפתח זה JSON אחד (system/market_settings.json) ו-API של market_service.
/p/{slug} עטופים בתבנית האתר.newpage_publicכדי שמתכנת חיצוני יוכל לעבוד עם WIZZO CMS בביטחון, לא מספיק קוד שעובד. צריך כללים כתובים, תיעוד שמתעדכן עם הקוד, ותהליך שמונע הפתעות. זה מה שהתקן מגדיר.
איך קוראים לקונטרולר, לפאנל, לטבלה ולמתודה. מה אסור (SQL מחובר במחרוזות, HTML בלי escape, גישה ישירה ל-system/) ומה חובה.
CRM_ דרך CONFIG::$db_fullprefix בלבדכל יכולת ציבורית מתועדת כאן. שינוי התנהגות בליבה מגיע עם עדכון הדף הרלוונטי באותו PR, ועם הערת "שימו לב" כשיש התנהגות מפתיעה.
מספר גרסה אחד (version.txt), הודעת commit במבנה קבוע עם מספר טיקט, Changelog, ובדיקות אוטומטיות לפני מיזוג. סודות אף פעם לא בריפו.