irgen-ext-php-shared-hosting
v0.1.2
Published
irgen extension for generating PHP-based blogging system deployable to shared hosting
Maintainers
Readme
irgen-ext-php-shared-hosting
A specialized irgen extension that generates a Hybrid App Platform for Shared Hosting. It combines a premium Blogging System with an Internal App Engine (MySQL + PHP REST API) for your React applications.
Note: This extension does not introduce a new frontend generator. All UI is compiled by
irgencore; the extension only provides backend targets and declarative presets.
Features
- ✅ Hybrid Engine: Supports both a public blog and private internal application logic.
- ✅ Automatic REST API: DSL
entity()declarations automatically become secure PHP REST endpoints. - ✅ MySQL Integration: Built-in PDO-based storage for business data, compatible with standard shared hosting.
- ✅ Zero-Config Backend: Generates a complete, secure PHP 7.4+ application.
- ✅ Premium Aesthetics: Refined blogging templates with modern typography and animations.
- ✅ SEO Ready: Automatic generation of
rss.xmlandsitemap.xml. - ✅ Internal App Presets: Use
adminPresetfor the blog manager andappPresetfor your custom apps. - ✅ Secure: Built-in CSRF protection, Session hardening, and PDO-based SQL injection prevention.
Usage (v0.1.1+)
1. Scaffolding a New Project
Use the irgen init command with the extension to jumpstart a PHP blogging system.
npx irgen init my-blog --ext=irgen-ext-php-shared-hosting --template=php-blog2. In Your DSL (irgen config)
Import the extension methods to configure your admin panel comfortably.
// app.dsl.ts (Data & Logic)
import { app } from "irgen";
app("MyProject", (t) => {
t.entity("Ticket", (e) => {
e.model({ title: "string", status: "string" });
e.list();
});
});
// ui.dsl.ts (Frontend Applications)
import { frontend } from "irgen";
import { adminPreset, appPreset } from "irgen-ext-php-shared-hosting";
// 1. Admin UI (Managed Blog + Tools)
frontend("admin", (f) => {
adminPreset({ adminBasePath: "/admin" })(f);
});
// 2. Internal User App (Custom React App)
frontend("portal", (f) => {
appPreset({ publicBasePath: "/portal" })(f);
});3. Running the Generator
Point irgen to your main DSL file (which imports any others).
# Generate both targets in one go
npx irgen app.dsl.ts \
--ext=irgen-ext-php-shared-hosting \
--targets=frontend,php-shared-hosting \
--outDir=generated/hybrid🏗️ Modern Architecture: Multi-DSL (Split DSL)
We recommend splitting your definition into two or more files (e.g., app.dsl.ts and ui.dsl.ts). To make this work, simply import your secondary DSLs into your main entry file:
// app.dsl.ts (Main Entry)
import { app } from "irgen";
import "./ui.dsl.ts"; // <--- Import your UI definitions
app("MyProject", (t) => { ... });This pattern provides:
- Separation of Concerns: Your data models (
entity()) and backend configurations stay clean from UI layouts. - Scalability: You can easily add more frontends (e.g., a Mobile App or a Landing Page) without bloating a single file.
- Shared Logic: Both the Admin UI and your User Portal will automatically see the same Entity schemas and use the same generated REST API.
Note: The
--extflag tellsirgento load this extension. The--targetsflag ensures both the frontend assets and the PHP backend are generated.
When you build the generated frontend (npm run build inside generated/.../frontend), the package.json includes a postbuild hook that copies the admin build into public/<adminBasePath> automatically (default: public/admin/).
When you generate both targets together, the backend emitter reads the adminPreset(...) options from the frontend app metadata. That means siteBasePath, adminBasePath, adminApiBasePath, and other options stay in sync without extra CLI flags.
The generated public/router.php reads config/app.config.php at runtime, so changes to siteBasePath, adminBasePath, and adminApiBasePath are reflected automatically.
Generated Output
generated/
├── app/ # PHP Application Core (Utils, Entity Logic)
├── config/ # Configuration (manifest, app.config.php)
├── data/ # Flat-file Store (Posts)
├── public/
│ ├── .htaccess # Master Routing (Multi-SPA + API)
│ ├── admin/ # React Admin UI
│ ├── portal/ # Custom User WebApp (example)
│ ├── api/ # Generated Entity REST Endpoints
│ ├── admin-api/ # Blog Management API
│ ├── site/ # Public Blog Frontend
│ └── uploads/ # User uploads
└── ...Admin Routes (v0)
/admin/posts list/admin/posts/newcreate post/admin/posts/:slugedit markdown (enter slug + markdown)
Admin UI Theming
The preset applies styling.themePack: "admin" so the generated UI uses the admin layout (sidebar + compact headers). It also marks intro components with uiVariant: "header" so page headers render inline instead of cards.
Generated Project README
Each generated project includes README.md with local test and deployment steps.
API Reference
adminPreset(options)
The main entry point. Creates a preset and applies it to your frontend builder.
Options:
| Option | Default | Description |
|--------|---------|-------------|
| deploymentMode | 'mode-a' | 'mode-a' (Secure, app/ outside public) or 'mode-b' (Single root) |
| adminBasePath | '/admin/' | URL path for the Admin UI |
| adminApiBasePath | '/admin-api/' | URL path for the PHP API |
| siteBasePath | '/site' | Base path for the public static site |
| siteBaseUrl | '' | Absolute base URL for canonical/RSS |
| siteTagline | '' | Tagline used for meta description |
| siteNav | [] | Nav items for public site header |
| siteTitle | '' | Title of your blog |
| postsDir | 'data/posts' | Where to store markdown files |
| db | See below | MySQL configuration (host, name, user, pass) |
appPreset(options)
Preset for consumer-facing React applications. It configures the app to connect to the generated PHP API and sets up correct deployment paths.
Options:
publicBasePath: The path where this app is hosted (e.g.,/app).
Database Configuration
If your DSL contains entity() definitions, you should provide MySQL credentials in t.meta("php-shared-hosting", { db: { ... } }) or during extension registration.
{
"host": "localhost",
"name": "your_db",
"user": "db_user",
"pass": "db_pass"
}Advanced Usage
For granular control, you can split the creation and application:
import { createAdminPreset, applyAdminPreset } from "...";
// 1. Create the Declarative Object
const decl = createAdminPreset({ ... });
// 2. Modify it (e.g. add a custom page)
decl.pages.push({ ... });
// 3. Apply it
frontend("admin", applyAdminPreset(decl));Deployment
Mode A (Recommended)
Upload public/ folder contents to your hosting's public_html. Place app/, config/, and data/ one level above public_html.
Mode B (Simple)
Upload everything to public_html. The generated .htaccess files will protect your code and data.
REST API + Auth + CORS
Endpoints live under adminApiBasePath (default /admin-api/) and use PHP sessions.
Full request/response documentation lives in extensions/php-shared-hosting/docs/REST-API.md.
Quick checks:
GET /admin-api/healthGET /admin-api/infoPOST /admin-api/auth/login(form-urlencoded)GET /admin-api/auth/me
Enable CORS (only if your admin UI is hosted on a different origin):
- Edit
config/app.config.php - Set
options.cors.enabled = true - Add your domain to
options.cors.allowedOrigins
- If
/admin-api/healthreturns HTML in local preview, your router is matching/adminbefore/admin-api. Ensure yourrouter.phpchecks/admin-apifirst with a strict prefix match.
Public site root:
- If you want the public site at
/, setsiteBasePath: ""in your options. The publisher will write output directly underpublic/instead ofpublic/site/.
License
MIT
