{"id":51301666,"url":"https://github.com/pavex/website","last_synced_at":"2026-06-30T20:30:41.038Z","repository":{"id":364147217,"uuid":"1234892499","full_name":"pavex/website","owner":"pavex","description":"The high-performance, SEO-centric PHP 8.0+ engine for developers who demand maximum control and zero bloat.","archived":false,"fork":false,"pushed_at":"2026-06-11T19:59:58.000Z","size":27,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-11T21:21:53.068Z","etag":null,"topics":["framework","mvc","php","website","website-template"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pavex.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-10T19:21:40.000Z","updated_at":"2026-06-11T20:00:44.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pavex/website","commit_stats":null,"previous_names":["pavex/website"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/pavex/website","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavex%2Fwebsite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavex%2Fwebsite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavex%2Fwebsite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavex%2Fwebsite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pavex","download_url":"https://codeload.github.com/pavex/website/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavex%2Fwebsite/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34983169,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-30T02:00:05.919Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["framework","mvc","php","website","website-template"],"created_at":"2026-06-30T20:30:40.254Z","updated_at":"2026-06-30T20:30:41.032Z","avatar_url":"https://github.com/pavex.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pavex Website\n\n**The high-performance, SEO-centric PHP 8.0+ engine for developers who demand maximum control and zero bloat.**\n\n[![PHP Version](https://img.shields.io/badge/php-%3E%3D8.0-8892bf.svg)](https://php.net)\n[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n\n---\n\n## 🌟 Philosophy: Beyond \"Just Another Framework\"\n\nPavex Website isn't a general-purpose application framework. It is a specialized, opinionated **Website Engine**. \n\nIn an era where web performance and Core Web Vitals directly impact business success, Pavex Website strips away the heavy abstractions of traditional MVC frameworks. It provides a surgical toolset for building content-driven sites that are lightning-fast, easy to maintain, and perfectly optimized for search engines from day one.\n\n### The \"Website-First\" Approach\nWhile other frameworks treat a \"website\" as a simplified \"web app,\" Pavex Website acknowledges that websites have unique requirements:\n- **Instant Response Times:** Minimal overhead between the request and the response.\n- **Semantic Integrity:** Total control over every byte of HTML output.\n- **Dynamic SEO:** First-class support for canonicals, meta tags, and structured data.\n- **Bi-directional Clarity:** Routing that is as easy to read as it is to write.\n\n---\n\n## Why Choose this package.\n\n- **Extreme Performance:** No heavy DI containers, no complex middleware stacks, no bloated ORM. Just raw PHP speed with a refined architectural structure.\n- **SEO Mastery:** Integrated `PageContext` makes managing complex SEO requirements (canonicals, OpenGraph, lang attributes, breadcrumbs) a part of your natural workflow, not an afterthought.\n- **Pure PHP Templates:** Forget learning yet another template syntax like Blade or Twig. Use pure PHP for logic and template inheritance that is both powerful and transparent.\n- **Integrity by Design:** Strict property visibility rules (Public for route args, Protected for templates) prevent common state-leakage bugs and make your code self-documenting.\n- **Smart Reverse Routing:** Change a URL pattern in one place, and every link across your entire site updates automatically. No more broken internal links.\n\n---\n\n## 🛠️ What Can You Build?\n\nPavex Website is the ideal foundation for:\n- **Corporate Portals:** Fast, accessible, and professional brand presences.\n- **Content Magazines \u0026 Blogs:** SEO-optimized platforms for publishers.\n- **Marketing Landing Pages:** High-conversion pages with no technical debt.\n- **Product Showcases:** Visually rich frontends backed by a clean data layer.\n- **E-commerce Frontends:** Performance-critical storefronts for modern shops.\n\n---\n\n## 🏗️ Core Architecture\n\nThe framework operates on three primary components:\n\n1.  **Router:** Maps URLs to Presenters (Input) and Presenters back to URLs (Output).\n2.  **Presenter:** The \"Controller\". It prepares data, manages SEO metadata, and triggers rendering.\n3.  **Control:** The orchestrator. It handles the request/response lifecycle and dependency injection.\n\n---\n\n## 🚦 Getting Started\n\n### 1. Installation\n\n```bash\ncomposer require pavex/website\n```\n\n### 2. Recommended Directory Structure\n\n```text\nsrc/\n  Website/\n    Application.php           # App bootstrapper\n    ApplicationContainer.php  # Service locator\n    Presenter/\n      BasePresenter.php       # Shared logic (SEO, common data)\n      HomePresenter.php       # Your first page\n      templates/\n        base.php              # Main layout\n        home.php              # Page template\n    Router/\n      WebsiteRules.php        # Route definitions\n```\n\n### 3. Creating a Presenter\n\nThe presenter lifecycle centers around the `render()` method.\n\n```php\nnamespace App\\Website\\Presenter;\n\nuse Pavex\\Website\\Presenter;\n\nfinal class HomePresenter extends BasePresenter\n{\n    // Public properties are automatically injected from route arguments\n    public string $section = 'default';\n\n    // Protected properties are available in the template via $this\n    protected array $features = [];\n\n    public function render(): ?string\n    {\n        // 1. Prepare SEO metadata\n        $this-\u003econtext-\u003etitle = 'Welcome to My Website';\n        $this-\u003econtext-\u003edescription = 'Building fast websites with Pavex.';\n        $this-\u003econtext-\u003ecanonical = $this-\u003elink($this);\n\n        // 2. Prepare data for template\n        $this-\u003efeatures = ['Speed', 'Simplicity', 'SEO'];\n\n        // 3. Trigger rendering (MANDATORY)\n        return parent::render();\n    }\n}\n```\n\n### 4. Creating a Template\n\nTemplates are located in the `templates/` subdirectory relative to the Presenter.\n\n```php\n// templates/home.php\n\u003c?php $parent('base'); ?\u003e\n\n\u003cmain\u003e\n    \u003ch1\u003eWelcome!\u003c/h1\u003e\n    \u003cp\u003eCurrent section: \u003c?= htmlspecialchars($this-\u003esection) ?\u003e\u003c/p\u003e\n\n    \u003cul\u003e\n        \u003c?php foreach ($this-\u003efeatures as $feature): ?\u003e\n            \u003cli\u003e\u003c?= htmlspecialchars($feature) ?\u003e\u003c/li\u003e\n        \u003c?php endforeach ?\u003e\n    \u003c/ul\u003e\n\u003c/main\u003e\n```\n\n### 5. Registering Routes\n\nRoutes are defined as pairs of `InputRule` and `OutputRule`.\n\n```php\n// src/Website/Router/WebsiteRules.php\nuse Pavex\\Website\\Router;\nuse Pavex\\Website\\ActionHandler;\n\n$rules = [];\n\n// URL -\u003e Presenter\n$rules[] = new Router\\InputRule('/^\\/$/', function ($match) use ($presenterConstructor) {\n    return new ActionHandler($presenterConstructor(HomePresenter::class), []);\n});\n\n// Presenter -\u003e URL (for $this-\u003elink())\n$rules[] = new Router\\OutputRule(HomePresenter::class, '/');\n\nreturn $rules;\n```\n\n---\n\n## 📖 Key Concepts\n\n### Property Visibility Rules\n\n| Visibility | Purpose | In Template |\n| :--- | :--- | :--- |\n| `public` | **Route Arguments**. Injected by `Control` before `render()`. | ✅ Yes |\n| `protected` | **Template Data**. Prepared inside `render()`. | ✅ Yes |\n| `private` | **Internal Logic**. Not accessible in templates. | ❌ No |\n\n### The `render()` Method\n\n- **Always** use `render(): ?string`. There is no `init()` method.\n- **Always** end with `return parent::render()`. Without this, your template will not render.\n\n### Link Generation\n\nNever hardcode URLs. Always use the Router to ensure links are always in sync with your rules.\n\n```php\n// Link to a class\n$url = $this-\u003elink(AboutPresenter::class);\n\n// Link with arguments\n$url = $this-\u003elink(PostPresenter::class, ['slug' =\u003e 'hello-world']);\n\n// Link to current page (canonical)\n$url = $this-\u003elink($this);\n```\n\n### SEO \u0026 Metadata (`PageContext`)\n\nThe `BasePresenter` (if extended) provides a `$this-\u003econtext` object to manage the `\u003chead\u003e` and `\u003cbody\u003e` tags.\n\n```php\n$this-\u003econtext-\u003etitle = 'Page Title';\n$this-\u003econtext-\u003eaddHeaderElement(['meta', ['name' =\u003e 'robots', 'content' =\u003e 'index,follow']]);\n$this-\u003econtext-\u003ecss('/assets/css/main.css');\n$this-\u003econtext-\u003eaddBodyClass('is-home');\n```\n\n---\n\n## 📜 License\n\nPavex Website is open-source software licensed under the [MIT license](LICENSE).\n\n---\n@author pavex@ines.cz\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpavex%2Fwebsite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpavex%2Fwebsite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpavex%2Fwebsite/lists"}