diff --git a/package.json b/package.json index 226d6f1..05aac28 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "dev": "astro dev", "start": "astro dev", "check": "astro check", - "build": "astro build", + "build": "astro build --force", "preview": "astro preview", "astro": "astro", "format": "prettier --write \"{src,public}/**/*.{astro,css,js,json,mjs,ts}\" \"*.{json,mjs,ts}\"", diff --git a/src/content/docs/404.mdoc b/src/content/docs/404.mdoc new file mode 100644 index 0000000..098b107 --- /dev/null +++ b/src/content/docs/404.mdoc @@ -0,0 +1,52 @@ +--- +title: Page Not Found +description: The requested FOSSBilling documentation page could not be found. +editUrl: false +lastUpdated: false +template: splash +tableOfContents: false +head: + - tag: meta + attrs: + name: robots + content: noindex +--- + +The page you are looking for may have moved, been renamed, or no longer exists. + +Start with one of the main documentation sections below, or use search to find the topic you need. + +{% cardgrid %} + {% linkcard + title="Getting Started" + href="/getting-started/" + description="Install FOSSBilling, check requirements, and prepare your environment." + /%} + {% linkcard + title="Maintenance" + href="/maintenance/" + description="Update, troubleshoot, and maintain an existing FOSSBilling installation." + /%} + {% linkcard + title="Admin Guide" + href="/admin-guide/" + description="Configure FOSSBilling and manage day-to-day administration tasks." + /%} + {% linkcard + title="Extensions & Development" + href="/extensions-and-development/" + description="Build modules, themes, payment gateways, and integrations." + /%} + {% linkcard + title="Support" + href="/support/" + description="Find FAQs, troubleshooting guidance, and community support links." + /%} + {% linkcard + title="GitHub Repository" + href="https://github.com/FOSSBilling/FOSSBilling" + description="Report issues or browse the FOSSBilling source code." + /%} +{% /cardgrid %} + +If you followed a link from the documentation site, please [open an issue](https://github.com/FOSSBilling/docs/issues/new) so it can be corrected. diff --git a/src/content/docs/admin-guide/company.mdoc b/src/content/docs/admin-guide/company.mdoc index a1a9e8f..7c5d565 100644 --- a/src/content/docs/admin-guide/company.mdoc +++ b/src/content/docs/admin-guide/company.mdoc @@ -20,12 +20,12 @@ Upload the logo assets FOSSBilling should use across the interface: ### Best Practices -- Store logos in your theme's `assets/` folder +- Upload custom logos through the settings page so updates do not overwrite them - Use SVG for crisp display at any size - Keep file sizes reasonable (< 500KB) {% aside type="caution" %} -Don't edit `themes/huraga/assets/img/logo.svg` directly — it's overwritten on updates. Upload your logo through the settings page instead. +Don't edit the bundled files in `public/branding/` directly. They are default assets and may be overwritten on updates. Upload your logo through the settings page instead. {% /aside %} ### Logo Not Showing? diff --git a/src/content/docs/extensions-and-development/file-structure.mdoc b/src/content/docs/extensions-and-development/file-structure.mdoc index cce05ea..f2c4931 100644 --- a/src/content/docs/extensions-and-development/file-structure.mdoc +++ b/src/content/docs/extensions-and-development/file-structure.mdoc @@ -18,6 +18,13 @@ Runtime data storage: This directory should be writable by the web server. +### `/src/public` + +Public core assets that must be web-accessible: +- **Assets** — Shared built browser assets (`/public/assets`), including the API wrapper, shared runtime, Markdown CSS, and CKEditor bundle +- **Branding** — Default logo, dark logo, and favicon (`/public/branding`) +- **Gateway icons** — Payment gateway logos (`/public/gateways`) + ### `/src/install` The installation wizard. Automatically deleted after installation unless `APP_ENV=dev` is set. @@ -28,7 +35,7 @@ Core PHP classes and business logic. #### `/src/library/Api` -Core API files including the JavaScript wrapper (`API.js`). [See the wrapper docs](/extensions-and-development/javascript/). +Core PHP API files. The browser-side API wrapper source now lives in `/frontend/core/api.js` and builds to `/src/public/assets/js/api.js`. [See the wrapper docs](/extensions-and-development/javascript/). #### `/src/library/Box` @@ -87,6 +94,19 @@ These are for shared hosting control panels. For VPS or game servers, consider c Translations as a Git submodule. Pointing to [github.com/FOSSBilling/locale](https://github.com/FOSSBilling/locale). +### `/frontend` + +Shared frontend source and build tooling: + +| Path | Purpose | +|------|---------| +| `core/` | Shared browser runtime and API wrapper source | +| `editor/` | CKEditor integration source | +| `styles/` | Shared CSS such as Markdown rendering styles | +| `tools/` | Common esbuild, Sass, PostCSS, asset copy, and PurgeCSS helpers used by theme builds | + +The root `npm run build` command builds this directory into `/src/public/assets`. + ### `/src/modules` All modules live here. Each module is a self-contained unit of functionality. @@ -122,6 +142,7 @@ Theme structure: ``` theme-name/ ├── assets/ # CSS, JS, images (built via esbuild) +│ └── build/ # Generated theme assets and manifest ├── config/ │ └── settings.html.twig # Theme settings UI ├── html/ # Twig templates diff --git a/src/content/docs/extensions-and-development/guides/creating-a-theme.mdoc b/src/content/docs/extensions-and-development/guides/creating-a-theme.mdoc index 396df50..0805c32 100644 --- a/src/content/docs/extensions-and-development/guides/creating-a-theme.mdoc +++ b/src/content/docs/extensions-and-development/guides/creating-a-theme.mdoc @@ -30,7 +30,8 @@ themes/mytheme/ ├── assets/ # CSS, JS, images (built via esbuild) │ ├── css/ │ ├── js/ -│ └── img/ +│ ├── img/ +│ └── build/ # Generated assets and manifest ├── config/ │ └── settings.html.twig # Theme settings UI (optional) ├── html/ # Your templates @@ -122,10 +123,19 @@ FOSSBilling provides [custom filters](/extensions-and-development/twig-filters) {{ price | format_currency(currency.code) }} {# Format currency #} {{ 'client/manage' | url(area: 'admin') }} {# Admin panel link #} {{ 'css/theme.css' | asset_url }} {# Theme asset URL #} +{{ 'js/api.js' | public_asset_url }} {# Shared core asset URL #} {{ date | timeago }} {# "2 hours ago" #} {{ content | markdown_to_html }} {# Parse Markdown #} ``` +Custom layouts that do not extend the bundled themes should load the shared runtime and API wrapper before theme JavaScript: + +```twig +{{ 'js/fossbilling.js'|public_asset_url|script_tag }} +{{ 'js/api.js'|public_asset_url|script_tag }} + +``` + ## Security Best Practices - Use `htmlspecialchars` when outputting user data diff --git a/src/content/docs/extensions-and-development/javascript.mdoc b/src/content/docs/extensions-and-development/javascript.mdoc index ecc449c..3bda7a8 100644 --- a/src/content/docs/extensions-and-development/javascript.mdoc +++ b/src/content/docs/extensions-and-development/javascript.mdoc @@ -19,7 +19,8 @@ If you're building themes or modules, use this wrapper instead of making raw bro The bundled admin and Huraga themes already load the wrapper. For a custom theme, add this to your base layout before your theme JavaScript: ```twig -{{ "Api/API.js"|library_url|script_tag }} +{{ 'js/fossbilling.js'|public_asset_url|script_tag }} +{{ 'js/api.js'|public_asset_url|script_tag }} ``` diff --git a/src/content/docs/extensions-and-development/twig-filters.mdoc b/src/content/docs/extensions-and-development/twig-filters.mdoc index 0d91c91..c240270 100644 --- a/src/content/docs/extensions-and-development/twig-filters.mdoc +++ b/src/content/docs/extensions-and-development/twig-filters.mdoc @@ -50,7 +50,7 @@ Project-specific filters and functions are defined in these classes: | Filter | Description | |--------|-------------| | `asset_url` | Get the URL for a theme asset. | -| `library_url` | Get the URL for the library folder. | +| `public_asset_url` | Get the URL for a shared core public asset built into `/public/assets`. | | `mod_asset_url` | Get the URL for a module asset. Use the asset path as the filtered value and the module name as the argument. | | `script_tag` | Generate an HTML ` +{{ 'js/fossbilling.js'|public_asset_url|script_tag }} +{{ 'js/api.js'|public_asset_url|script_tag }} -{# API form handled by Api/API.js #} +{# API form handled by the shared API wrapper #}
+{# Shared editor bundle #} +{{ wysiwyg('.editor-textarea') }} + {# API link with a confirmation modal #} diff --git a/src/content/docs/getting-started/building.mdoc b/src/content/docs/getting-started/building.mdoc index 22b1c85..56bdc3a 100644 --- a/src/content/docs/getting-started/building.mdoc +++ b/src/content/docs/getting-started/building.mdoc @@ -14,7 +14,7 @@ Build FOSSBilling from source when you want to contribute code, test changes loc Make sure you have: - PHP 8.3 or newer - [Composer](https://getcomposer.org/) (latest version) -- [Node.js](https://nodejs.org/) (LTS version) with npm +- [Node.js](https://nodejs.org/) with npm 11 or newer {% /aside %} ## Build Steps @@ -46,6 +46,8 @@ Make sure you have: npm run build ``` + This builds the shared frontend assets into `src/public/assets` and builds the bundled `admin_default` and `huraga` theme assets. + 5. **Add translations** (optional) Download the [latest translations](https://github.com/FOSSBilling/locale/releases/tag/latest) and extract to `src/locale/`, overwriting existing files. @@ -54,13 +56,19 @@ After these steps, your checkout is ready for local development or for packaging ## Development Mode -For active development: +For active theme development, use the theme workspace scripts: ```bash -npm run dev +npm run build-admin_default +npm run build-huraga ``` -This watches files and rebuilds automatically when you make changes. +The Huraga theme also supports watch mode: + +```bash +cd src/themes/huraga +npm run dev +``` ## Running Locally @@ -71,4 +79,4 @@ cd src php -S localhost:8000 ``` -Then visit `http://localhost:8000` in your browser. \ No newline at end of file +Then visit `http://localhost:8000` in your browser. diff --git a/src/content/docs/getting-started/docker.mdoc b/src/content/docs/getting-started/docker.mdoc index 7edc337..1b67130 100644 --- a/src/content/docs/getting-started/docker.mdoc +++ b/src/content/docs/getting-started/docker.mdoc @@ -21,42 +21,45 @@ Use the `latest` tag for the current stable release. The simplest option. This runs only the FOSSBilling container, so you must provide your own database service. ```bash -docker run -d -p 80:80 \ +docker run -d \ + --name fossbilling \ + -p 80:80 \ -v fossbilling:/var/www/html \ - --restart=always \ + --restart unless-stopped \ fossbilling/fossbilling:latest ``` Then open your server IP or hostname in a browser to complete the web installer. {% /tabitem %} {% tabitem label="Docker Compose" %} -This option brings up FOSSBilling and MySQL together, which makes it the fastest way to get started. +This option brings up FOSSBilling and MariaDB together, which makes it the fastest way to get started. -```yaml -version: "3.9" +```yaml {% meta="title='docker-compose.yml'" %} services: fossbilling: image: fossbilling/fossbilling:latest - restart: always + restart: unless-stopped ports: - - 80:80 + - "80:80" volumes: - fossbilling:/var/www/html + depends_on: + - mariadb - mysql: - image: mysql:8.4 - restart: always + mariadb: + image: mariadb:lts + restart: unless-stopped environment: - MYSQL_DATABASE: fossbilling - MYSQL_USER: fossbilling - MYSQL_PASSWORD: ${MYSQL_PASSWORD:?set-a-strong-database-password} - MYSQL_RANDOM_ROOT_PASSWORD: '1' + MARIADB_DATABASE: fossbilling + MARIADB_USER: fossbilling + MARIADB_PASSWORD: ${MARIADB_PASSWORD:?set-a-strong-database-password} + MARIADB_RANDOM_ROOT_PASSWORD: "1" volumes: - - mysql:/var/lib/mysql + - mariadb:/var/lib/mysql volumes: fossbilling: - mysql: + mariadb: ``` Run it: @@ -70,14 +73,14 @@ The first startup downloads container images, so it may take a few minutes. Before starting the stack, set a strong database password: ```bash -export MYSQL_PASSWORD="$(openssl rand -base64 32)" +export MARIADB_PASSWORD="$(openssl rand -base64 32)" ``` **Database credentials** (if using the example above): -- Hostname: `mysql` +- Hostname: `mariadb` - Database: `fossbilling` - Username: `fossbilling` -- Password: the value of `MYSQL_PASSWORD` +- Password: the value of `MARIADB_PASSWORD` Open `http://localhost` or your server's IP/hostname to continue with the installer. {% /tabitem %} @@ -85,8 +88,6 @@ Open `http://localhost` or your server's IP/hostname to continue with the instal ## Post-Installation -After installation, set up the cron job on your host: +The official Docker image runs FOSSBilling cron automatically every five minutes inside the container. -```bash -(crontab -l; echo "*/5 * * * * docker exec su www-data -s /usr/local/bin/php /var/www/html/cron.php") | awk '!x[$0]++' | crontab - -``` \ No newline at end of file +You do not need to add a host crontab entry when using the official Docker image. \ No newline at end of file diff --git a/src/content/docs/getting-started/installation.mdoc b/src/content/docs/getting-started/installation.mdoc index b8438d1..c5c3212 100644 --- a/src/content/docs/getting-started/installation.mdoc +++ b/src/content/docs/getting-started/installation.mdoc @@ -76,8 +76,8 @@ server { return 403; } - # Deny access to /data, except /assets/gateways - location ~* /data/(?!(assets/gateways/)) { + # Deny access to runtime data + location ^~ /data/ { return 403; } @@ -114,7 +114,7 @@ server { ## Pre-installation Steps 1. **Download FOSSBilling**: Download the latest [stable release](https://fossbilling.org/downloads) from our downloads page. -2. **Prepare your database**: Create a new MySQL database and a dedicated user for this installation. Keep the credentials handy for the installer. +2. **Prepare your database**: Create a new MariaDB/MySQL database and a dedicated user for this installation. Keep the credentials handy for the installer. 3. **Set up SSL**: If you plan to use HTTPS, and you should, configure and verify your certificate *before* you start the installer. 4. **Configure reverse-proxy headers**: If you run behind a reverse proxy, forward the `X-Forwarded-Host` and `X-Forwarded-Proto` headers so FOSSBilling can generate the correct URLs and enforce HTTPS properly. diff --git a/src/content/docs/getting-started/requirements.mdoc b/src/content/docs/getting-started/requirements.mdoc index 87b0fdc..be97967 100644 --- a/src/content/docs/getting-started/requirements.mdoc +++ b/src/content/docs/getting-started/requirements.mdoc @@ -40,5 +40,5 @@ Use `utf8mb4` with `utf8mb4_unicode_ci` collation. Your database user needs full FOSSBilling requires a MySQL-compatible database: -- **MySQL** 8.0 or newer -- **MariaDB** 10.3 or newer \ No newline at end of file +- **MySQL** 8.4 or newer +- **MariaDB** 11.4 or newer \ No newline at end of file diff --git a/src/content/docs/index.mdoc b/src/content/docs/index.mdoc index 9c7df6a..6b317ad 100644 --- a/src/content/docs/index.mdoc +++ b/src/content/docs/index.mdoc @@ -2,6 +2,11 @@ title: Introduction description: Learn what FOSSBilling is, where to start, and how to get involved with the project. tableOfContents: false +banner: + content: | + 0.8.0 is here! Check out the + release notes + and upgrade guide for details. --- FOSSBilling (*FOSS*: Free and Open Source Software) is a billing and client management solution for hosting providers and digital service businesses. diff --git a/src/content/docs/maintenance/Updating/0-7-to-0-8.mdoc b/src/content/docs/maintenance/Updating/0-7-to-0-8.mdoc new file mode 100644 index 0000000..743bd0b --- /dev/null +++ b/src/content/docs/maintenance/Updating/0-7-to-0-8.mdoc @@ -0,0 +1,426 @@ +--- +title: Upgrading from 0.7.x to 0.8.0 +description: Version-specific upgrade notes for moving a FOSSBilling 0.7.x installation to 0.8.0. +sidebar: + label: 0.7.x to 0.8.0 + order: 2 + badge: + text: New +--- + +The 0.8.0 release includes significant database, structural, and frontend changes. Read every section below before upgrading. + +{% aside type="caution" %} +**Review custom themes and modules carefully.** 0.8.0 removes jQuery, switches from Webpack Encore to esbuild, replaces the routing layer with Symfony HttpKernel, and introduces multiple Twig filter removals and renames. Custom code that depends on the old infrastructure will break. +{% /aside %} + +## PHP Requirement + +The minimum PHP version has been raised from 8.1 to **8.3**. Verify your server meets this requirement before upgrading. + +## Database & Charset Migration + +The database charset has been migrated from `utf8` to `utf8mb4` / `utf8mb4_unicode_ci`. The patcher handles this automatically. + +## Configuration Changes + +- `db.type` has been renamed to `db.driver` and its value changed from `'mysql'` to `'pdo_mysql'`. The patcher migrates this for you. +- Old `api.rate_*` settings (`rate_span`, `rate_limit`, `throttle_delay`, `rate_span_login`, `rate_limit_login`, `rate_limit_whitelist`) have been replaced by the new `rate_limiter` block. The patcher will prompt you to accept the new defaults. +- The `url` setting no longer stores the protocol prefix; it is stripped on save. +- New `security.trusted_proxies` block for configuring reverse proxy trust. +- New `security.session_regeneration_grace_period` setting (default: 300). +- New `i18n.auto_detect_locale`, `i18n.date_format`, `i18n.time_format`, `i18n.datetime_pattern` settings. + +## Module Migrations + +The following modules have been removed or replaced. The patcher handles the migration automatically, but you may need to review your configuration afterward: + +| Change | Details | +|--------|---------| +| `Servicemembership` removed | Membership products and orders are migrated to the "custom" product type. Review active membership orders after updating. | +| `Spamchecker` replaced | Replaced by the new `Antispam` module (supports Cloudflare Turnstile, hCaptcha, and honeypot fields). Review your spam-protection settings after the update. | +| `Wysiwyg` removed | CKEditor 5 is now integrated directly into themes. Use the `wysiwyg` Twig function to initialize editors. | +| `Paidsupport` removed | Module data is cleaned up. | +| Added `Antispam` | New spam-prevention module with multiple challenge providers. | +| Added `Widgets` | New module for registering renderable widget slots in templates. | + +## Uploads Directory + +The uploads directory has moved from `/uploads` to `/data/uploads`. Files are migrated automatically. If you have web-server rules referencing the old path, update them: + +{% tabs %} +{% tabitem label="NGINX" %} +```nginx +# Old rule (0.7.x): +location ~* /uploads/.*\.php$ { return 403; } + +# Updated for 0.8.0: +location ^~ /data/ { return 403; } +``` +{% /tabitem %} +{% tabitem label="Apache (.htaccess)" %} +The bundled `.htaccess` is updated automatically with the new release. If you maintain a custom `.htaccess`, update it to block `/data/` instead of `/uploads/`. +{% /tabitem %} +{% /tabs %} + +## Template Directory Restructure + +Module templates have been moved from the old `html_*` directory names to a `templates/` structure. Theme directories (`html/` and `html_custom/`) are unchanged. + +| Old path | New path | +|----------|----------| +| `modules/{Module}/html_admin/` | `modules/{Module}/templates/admin/` | +| `modules/{Module}/html_client/` | `modules/{Module}/templates/client/` | +| `modules/{Module}/html_email/` | `modules/{Module}/templates/email/` | + +The patcher removes the old `html_*` directories from modules. If you have custom modules, **update your file structure before applying the patches**, or the old directories will be deleted and you will lose your changes. + +## Public Assets + +Shared browser assets now live in `/public` instead of `/data/assets` or theme-specific fallback paths: + +| Asset | New location | +|-------|--------------| +| Gateway icons | `/public/gateways/` | +| Default logo, dark logo, and favicon | `/public/branding/` | +| Shared JavaScript, Markdown CSS, and CKEditor bundles | `/public/assets/` | + +The patcher migrates bundled gateway icons and default branding settings automatically. If you maintain custom web-server rules, make sure `/public` remains publicly readable while `/data` remains blocked. + +## Theme & Frontend Changes + +### Build System: Webpack Encore → esbuild + +The front-end build system has been migrated from [Webpack Encore](https://symfony.com/doc/current/frontend.html) to [esbuild](https://esbuild.github.io/). + +- Bundled theme `package.json` scripts now call local `esbuild.mjs` files instead of Webpack Encore. Huraga's `dev` script uses `node ./esbuild.mjs --watch`; `admin_default` uses `node ./esbuild.mjs` for both `dev` and `build`. +- Shared build helpers are in `frontend/tools/esbuild-helpers.mjs` (at the repository root). +- Theme-specific build scripts are at `src/themes/{theme}/esbuild.mjs`. + +If you maintain a custom theme with its own build pipeline, update it for the new asset structure and Twig loading pattern. You can keep another build tool if it outputs compatible assets, but the bundled `huraga` and `admin_default` themes now use esbuild and are the best reference implementations. + +### Asset Loading + +Replace `encore_entry_link_tags` / `encore_entry_script_tags` with direct CSS and JS asset tags: + +{% tabs %} +{% tabitem label="Before (0.7.x)" %} +```twig +{{ encore_entry_link_tags('fossbilling') }} +{{ "Api/API.js" | library_url | script_tag }} +{{ encore_entry_script_tags('fossbilling') }} +``` +{% /tabitem %} +{% tabitem label="After (0.8.0)" %} +```twig + + +{{ 'js/fossbilling.js' | public_asset_url | script_tag }} +{{ 'js/api.js' | public_asset_url | script_tag }} + +``` +{% /tabitem %} +{% /tabs %} + +### jQuery Removed + +jQuery has been removed from both bundled themes. All admin and client templates have been migrated to vanilla JavaScript. + +- The old `bb` JavaScript object and `bb.redirect()` no longer exist. Use `window.location` instead. +- `$(function() { ... })` → `document.addEventListener("DOMContentLoaded", function() { ... })` +- Any custom theme or module JavaScript that depends on jQuery must be rewritten. + +### JavaScript API Wrapper + +The JS API wrapper has been rewritten and moved from `library/Api/API.js` to `frontend/core/api.js`. The browser call pattern (`API.admin.post`, `API.client.get`, `API.guest.get`, etc.) remains compatible, and the related Twig helpers (`fb_api_form`, `fb_api_link`) are still available, but the internal implementation is entirely new. + +Load it with: +```twig +{{ 'js/fossbilling.js' | public_asset_url | script_tag }} +{{ 'js/api.js' | public_asset_url | script_tag }} +``` + +The old `library_url` filter used for `{{ "Api/API.js" | library_url | script_tag }}` has been removed. + +### Frontend Directory Structure + +Shared frontend source code has moved to a new `frontend/` directory at the repository root: + +``` +frontend/ +├── core/ +│ ├── api.js # JavaScript API wrapper +│ └── fossbilling.js # Runtime helpers (message toasts, request utilities) +├── editor/ +│ └── ckeditor.js # CKEditor 5 bundle +├── styles/ +│ └── markdown.css # Markdown content styling +└── tools/ + └── esbuild-helpers.mjs # Shared build utilities +``` + +### Debug Bar + +The `DebugBar_renderHead()` Twig function has been renamed to `debug_bar_render_head()`: + +{% tabs %} +{% tabitem label="Before (0.7.x)" %} +```twig +{{ DebugBar_renderHead() }} +``` +{% /tabitem %} +{% tabitem label="After (0.8.0)" %} +```twig +{{ debug_bar_render_head() }} +``` +{% /tabitem %} +{% /tabs %} + +### CSRF Meta Tag Removed + +The `` tag has been removed from bundled themes. CSRF tokens are now sent via cookie (`csrf_token`) and handled automatically by the JavaScript API wrapper. If your custom theme relies on the meta tag, switch to reading the cookie: + +```javascript +const token = document.cookie.match(/csrf_token=([^;]*)/)?.[1] || ''; +``` + +Build output is written to theme/public asset directories such as `src/public/assets`, not to a tracked `frontend/build` directory. + +### Twig Globals + +Available Twig globals to review when updating custom templates include: + +| Global | Description | +|--------|-------------| +| `app_area` | `"admin"` or `"client"` | +| `current_theme` | The active theme code | +| `request` | Query parameters from the current request | +| `request_query` | Original query parameters array | +| `request_path` | Normalized route path | +| `request_has_filters` | Boolean indicating active filters in the request | +| `default_currency` | The default currency code | +| `FOSSBillingVersion` | The current version string | + +### Twig Filter Changes + +The following filters have been **removed**: + +| Removed filter | Replacement | +|----------------|-------------| +| `alink` | `url` with `area: 'admin'` — `{{ 'staff/login' \| url({area: 'admin'}) }}` | +| `link` | `url` — `{{ 'order' \| url }}` | +| `gravatar` | `avatar` function — `{{ avatar(email, 80) }}` (uses DiceBear locally) | +| `library_url` | `public_asset_url` | +| `markdown` | `markdown_to_html` — `{{ content \| markdown_to_html }}` | +| `size` | `file_size` — `{{ 1048576 \| file_size }}` | +| `number` | `format_number` (from Twig Intl Extra) | +| `money` / `money_without_currency` | `format_currency` — `{{ 29.99 \| format_currency('USD') }}` | +| `money_convert` / `money_convert_without_currency` | No direct Twig filter replacement. Convert the amount before rendering, then format it with `format_currency`. | +| `img_tag` | Use standard `` HTML | +| `iplookup` | Removed. | +| `ipcountryname` | Renamed to `ip_country_name` | +| `autolink` | Removed. | + +The following filters and functions have been **added**: + +| New filter/function | Description | +|---------------------|-------------| +| `public_asset_url` | URL for shared core assets in `/public` | +| `url` | Now accepts `area` parameter (`'admin'` / `'client'`) to replace both old `alink` and `link` | +| `has_permission` | Check admin module permission in templates | +| `render_widgets` | Render widgets for a named slot | +| `svg_sprite` | Render the theme's SVG icon sprite | +| `antispam_honeypot` | Return honeypot configuration array | +| `wysiwyg` | Initialize CKEditor 5 on a textarea selector | +| `avatar` | Generate DiceBear avatar image for an email address | +| `script_tag` | Generate `