Skip to content

Creating a Theme

FOSSBilling uses Twig for templating. Themes work by overriding the templates shipped by modules:

  1. Module provides a default template (modules/example/html_client/template.twig)
  2. Your theme provides an override (themes/mytheme/html/template.twig)
  3. FOSSBilling uses your theme's version

FOSSBilling loads templates in this order (highest priority first):

  1. themes/mytheme/html_custom/ — User customizations
  2. themes/mytheme/html/ — Your theme files
  3. modules/example/html_client/ — Module defaults
themes/mytheme/
├── assets/ # CSS, JS, images
│ ├── css/
│ ├── js/
│ └── img/
├── config/
│ └── settings.html.twig # Theme settings UI (optional)
├── html/ # Your templates
│ ├── layouts/
│ │ └── default.twig # Base layout
│ ├── partials/
│ │ ├── header.twig
│ │ └── footer.twig
│ └── index.twig # Homepage
├── html_custom/ # For user customizations (leave empty)
└── manifest.json # Theme metadata
{
"id": "mytheme",
"name": "My Theme",
"description": "A custom FOSSBilling theme",
"version": "1.0.0",
"author": "Your Name",
"author_url": "https://example.com",
"icon": "icon.png"
}

All API calls need a CSRF token. Access it in templates as CSRFToken:

In a form:

<input type="hidden" name="CSRFToken" value="{{ CSRFToken }}"/>

In a link:

<a href="{{ 'api/admin/client/group_delete'|link({ 'id': group.id, 'CSRFToken': CSRFToken }) }}">
Delete
</a>

Access API endpoints directly in Twig (no CSRF token needed):

{{ guest.currency_get_pairs }}
{{ guest.system_version }}
{{ client.invoice_get_list({ 'per_page': 10 }) }}
{{ admin.staff_group_get_pairs }}
{{ admin.extension_config_get({ 'ext': 'mod_seo' }) }}

FOSSBilling provides custom filters for themes:

{{ price | money }} {# Format currency #}
{{ 'client/manage' | alink }} {# Admin panel link #}
{{ 'theme.css' | asset_url }} {# Theme asset URL #}
{{ date | timeago }} {# "2 hours ago" #}
{{ content | markdown }} {# Parse Markdown #}
  • Use htmlspecialchars when outputting user data
  • Validate all inputs
  • Include CSRF tokens in forms
  • See the security docs for more
  1. Place your theme in /themes/mytheme/
  2. Go to Settings → Themes in the admin panel
  3. Select and activate your theme
  4. Check both client and admin areas
  5. Test on different screen sizes