You've already forked framexEngine-pro
416 lines
7.5 KiB
Markdown
416 lines
7.5 KiB
Markdown
# Framex Engine Documentation
|
|
|
|
Framex is a small PHP engine for building fast websites with plain PHP views, Markdown pages, reusable templates, and Tailwind CSS 4. It is designed to stay simple: URLs map to files, templates wrap views, and assets live in `public`.
|
|
|
|
## Project Structure
|
|
|
|
The important folders are:
|
|
|
|
```text
|
|
app/views/ Page views for URLs
|
|
core/ Router, renderer, helpers, and configuration
|
|
templates/ Layout templates and partials
|
|
templates/partials/ Shared pieces such as top menu and footer
|
|
public/ Web root for CSS, JS, images, and index.php
|
|
public/css/src/ Tailwind source CSS
|
|
public/css/style.css Compiled production CSS
|
|
public/js/init.js Theme toggle and menu behavior
|
|
```
|
|
|
|
The web server should point to `public` as the document root.
|
|
|
|
## URL Routing
|
|
|
|
Framex resolves the browser URL to a file inside `app/views`.
|
|
|
|
For a request like:
|
|
|
|
```text
|
|
/about
|
|
```
|
|
|
|
Framex checks these files in order:
|
|
|
|
```text
|
|
app/views/about.php
|
|
app/views/about/index.php
|
|
app/views/about.md
|
|
app/views/about/index.md
|
|
```
|
|
|
|
The first file that exists is rendered. If none exists, Framex falls back to `templates/error404.php`.
|
|
|
|
Examples:
|
|
|
|
```text
|
|
/ -> app/views/index.php
|
|
/docs -> app/views/docs/index.md
|
|
/about -> app/views/about/index.md
|
|
/pricing -> app/views/pricing.php
|
|
/blog/hello -> app/views/blog/hello.php or app/views/blog/hello/index.md
|
|
```
|
|
|
|
Trailing slashes are normalized, so `/docs/` and `/docs` resolve the same way.
|
|
|
|
## PHP Views
|
|
|
|
Use PHP views when a page needs custom markup, variables, conditionals, loops, forms, or reusable PHP logic.
|
|
|
|
Create a file:
|
|
|
|
```text
|
|
app/views/pricing.php
|
|
```
|
|
|
|
Then visit:
|
|
|
|
```text
|
|
/pricing
|
|
```
|
|
|
|
A PHP view can set page metadata by assigning values to the `$data` array:
|
|
|
|
```php
|
|
<?php
|
|
$data['title'] = 'Pricing - Framex';
|
|
$data['metaDescription'] = 'Simple pricing page built with Framex.';
|
|
$data['bodyClass'] = 'bg-slate-50 text-slate-950 dark:bg-slate-950 dark:text-slate-100';
|
|
?>
|
|
|
|
<main class="section">
|
|
<div class="contain">
|
|
<h1 class="text-4xl font-semibold">Pricing</h1>
|
|
<p class="mt-4 text-slate-600 dark:text-slate-400">Choose the right plan.</p>
|
|
</div>
|
|
</main>
|
|
```
|
|
|
|
The rendered PHP view is injected into the main template through `<?= $view ?>`.
|
|
|
|
## Markdown Views
|
|
|
|
Use Markdown views for documentation, simple content pages, articles, and static text-heavy pages.
|
|
|
|
Create a file:
|
|
|
|
```text
|
|
app/views/guide/index.md
|
|
```
|
|
|
|
Then visit:
|
|
|
|
```text
|
|
/guide
|
|
```
|
|
|
|
Markdown files are parsed by `Parsedown` and automatically wrapped in:
|
|
|
|
```html
|
|
<article class="prose prose-shell">
|
|
...
|
|
</article>
|
|
```
|
|
|
|
That means Markdown pages automatically get readable typography, spacing, links, lists, code blocks, tables, blockquotes, images, and light/dark colors.
|
|
|
|
Example Markdown page:
|
|
|
|
```md
|
|
# My Guide
|
|
|
|
This page is rendered from Markdown.
|
|
|
|
## Features
|
|
|
|
- Clean URLs
|
|
- Automatic styling
|
|
- Light and dark mode
|
|
|
|
```php
|
|
echo 'Code blocks are styled too';
|
|
```
|
|
```
|
|
|
|
## Templates
|
|
|
|
The default layout is:
|
|
|
|
```text
|
|
templates/main.php
|
|
```
|
|
|
|
It handles:
|
|
|
|
- HTML document structure
|
|
- Meta tags
|
|
- CSS include
|
|
- Dark-mode bootstrap
|
|
- Top menu partial
|
|
- Current view output
|
|
- Footer partial
|
|
- JavaScript include
|
|
|
|
The main content flow is:
|
|
|
|
```php
|
|
<?= partial('topmenu') ?>
|
|
<?= $view ?>
|
|
<?= partial('footer') ?>
|
|
```
|
|
|
|
Partials live in:
|
|
|
|
```text
|
|
templates/partials/
|
|
```
|
|
|
|
For example:
|
|
|
|
```text
|
|
templates/partials/topmenu.php
|
|
templates/partials/footer.php
|
|
```
|
|
|
|
Load a partial with:
|
|
|
|
```php
|
|
<?= partial('topmenu') ?>
|
|
```
|
|
|
|
## Metadata
|
|
|
|
PHP views can customize metadata with `$data`.
|
|
|
|
Common keys:
|
|
|
|
```php
|
|
$data['title'] = 'Page title';
|
|
$data['metaDescription'] = 'Page description for search and sharing.';
|
|
$data['metaImage'] = image(1200, 630);
|
|
$data['bodyClass'] = 'custom body classes';
|
|
$data['template'] = 'main';
|
|
```
|
|
|
|
If a key is not set, `templates/main.php` uses sensible defaults.
|
|
|
|
Markdown views currently use the default metadata unless the renderer is extended to read front matter.
|
|
|
|
## Assets
|
|
|
|
Public files are served from `public`.
|
|
|
|
Examples:
|
|
|
|
```text
|
|
public/css/style.css -> /css/style.css
|
|
public/js/init.js -> /js/init.js
|
|
public/images/logo.png -> /images/logo.png
|
|
```
|
|
|
|
Use the `asset()` helper for cache-busted URLs:
|
|
|
|
```php
|
|
<link rel="stylesheet" href="<?= asset('css/style.css') ?>">
|
|
<script src="<?= asset('js/init.js', ['prefix' => 'framex', 'hash' => true]) ?>"></script>
|
|
```
|
|
|
|
Useful asset options:
|
|
|
|
```php
|
|
asset('css/style.css');
|
|
asset('js/init.js', ['hash' => true]);
|
|
asset('images/logo.png', ['absolute' => true]);
|
|
asset('images/missing.png', ['fallback' => '/images/default.png']);
|
|
```
|
|
|
|
## Tailwind CSS
|
|
|
|
Framex uses Tailwind CSS 4 through the Tailwind CLI.
|
|
|
|
Install dependencies:
|
|
|
|
```bash
|
|
npm install
|
|
```
|
|
|
|
Build CSS:
|
|
|
|
```bash
|
|
npm run build:css
|
|
```
|
|
|
|
Watch CSS during development:
|
|
|
|
```bash
|
|
npm run watch:css
|
|
```
|
|
|
|
Source CSS:
|
|
|
|
```text
|
|
public/css/src/style.css
|
|
```
|
|
|
|
Compiled CSS:
|
|
|
|
```text
|
|
public/css/style.css
|
|
```
|
|
|
|
Tailwind scans these sources:
|
|
|
|
```css
|
|
@source "../../../templates/**/*.php";
|
|
@source "../../../app/**/*.php";
|
|
@source "../../../app/**/*.md";
|
|
```
|
|
|
|
When you add new Tailwind classes in PHP or Markdown files, rebuild the CSS.
|
|
|
|
## Reusable CSS Classes
|
|
|
|
The project includes reusable classes in `public/css/src/style.css`.
|
|
|
|
Layout:
|
|
|
|
```html
|
|
<section class="section">
|
|
<div class="contain">...</div>
|
|
</section>
|
|
```
|
|
|
|
Buttons:
|
|
|
|
```html
|
|
<a class="btn btn-primary" href="/docs">Primary</a>
|
|
<a class="btn btn-secondary" href="/about">Secondary</a>
|
|
<button class="btn btn-ghost">Ghost</button>
|
|
```
|
|
|
|
Cards:
|
|
|
|
```html
|
|
<article class="card">
|
|
<h2>Card title</h2>
|
|
<p>Card content.</p>
|
|
</article>
|
|
```
|
|
|
|
Preset backgrounds:
|
|
|
|
```html
|
|
<div class="bg-pre-blue">Blue preset</div>
|
|
<div class="bg-pre-emerald">Emerald preset</div>
|
|
<div class="bg-pre-amber">Amber preset</div>
|
|
<div class="bg-pre-rose">Rose preset</div>
|
|
```
|
|
|
|
These presets include both light and dark colors.
|
|
|
|
## Light and Dark Mode
|
|
|
|
Dark mode is controlled by the `dark` class on the `<html>` element.
|
|
|
|
The inline script in `templates/main.php` runs before the stylesheet loads. It checks:
|
|
|
|
1. The saved `framex-theme` value in `localStorage`.
|
|
2. The browser system preference.
|
|
3. Light mode as the fallback.
|
|
|
|
The toggle buttons in `templates/partials/topmenu.php` use:
|
|
|
|
```html
|
|
data-theme-toggle
|
|
```
|
|
|
|
The behavior is implemented in:
|
|
|
|
```text
|
|
public/js/init.js
|
|
```
|
|
|
|
Use Tailwind dark variants anywhere:
|
|
|
|
```html
|
|
<div class="bg-white text-slate-950 dark:bg-slate-900 dark:text-white">
|
|
Theme-aware content
|
|
</div>
|
|
```
|
|
|
|
## Running Locally
|
|
|
|
Install dependencies and build CSS:
|
|
|
|
```bash
|
|
npm install
|
|
npm run build:css
|
|
```
|
|
|
|
Start PHP's built-in server:
|
|
|
|
```bash
|
|
php -S localhost:8000 -t public
|
|
```
|
|
|
|
Open:
|
|
|
|
```text
|
|
http://localhost:8000/
|
|
```
|
|
|
|
Useful URLs:
|
|
|
|
```text
|
|
/ Landing page
|
|
/docs This documentation
|
|
/about Example Markdown page
|
|
```
|
|
|
|
## Adding a New Page
|
|
|
|
For a PHP page:
|
|
|
|
```text
|
|
app/views/services.php
|
|
```
|
|
|
|
Visit:
|
|
|
|
```text
|
|
/services
|
|
```
|
|
|
|
For a Markdown page:
|
|
|
|
```text
|
|
app/views/services/index.md
|
|
```
|
|
|
|
Visit:
|
|
|
|
```text
|
|
/services
|
|
```
|
|
|
|
For a nested page:
|
|
|
|
```text
|
|
app/views/blog/hello-world/index.md
|
|
```
|
|
|
|
Visit:
|
|
|
|
```text
|
|
/blog/hello-world
|
|
```
|
|
|
|
## Recommended Workflow
|
|
|
|
1. Add or edit a PHP or Markdown view in `app/views`.
|
|
2. Use `templates/partials` for shared UI.
|
|
3. Use `.section`, `.contain`, `.btn`, `.card`, and preset backgrounds for consistent design.
|
|
4. Run `npm run build:css` after changing Tailwind classes.
|
|
5. Test the URL in the browser.
|
|
|
|
Framex works best when pages stay close to the filesystem, shared layout stays in templates, and reusable styling stays in the Tailwind source CSS.
|