User Docs Developer Docs | |

theme_info.json Reference

The theme manifest file. Read at discovery time and on every admin Themes page load.

Important Change 2.2.x to 2.3.x Same changes as plugin_info.json above — remove slug, add free field, add required fields note, add URL fields table. Cron registration is plugin-only.

Complete Example

{
    "name": "Default",
    "version": "2.1.0",
    "min_pubvana_version": "2.2.3",
    "max_pubvana_version": "2.2.4",
    "update_url": "https://pubvana.net/api/dstore/v1/update/check",
    "author": "Pubvana",
    "author_url": "https://pubvana.net",
    "support_url": "https://pubvana.net/contact",
    "description": "Clean Bootstrap 5 theme.",
    "screenshot": "screenshot.png",
    "css_framework": "Bootstrap",
    "css_frame_ver": "5.x",
    "icon_pack": "FontAwesome",
    "icon_pack_ver": "6.x",
    "js_framework": "Bootstrap",
    "js_framework_ver": "5.x",
    "widget_areas": {
        "sidebar": "Main Sidebar",
        "footer-1": "Footer Column 1",
        "footer-2": "Footer Column 2",
        "footer-3": "Footer Column 3",
        "before-content": "Before Content"
    },
    "options": {
        "show_sidebar": {
            "type": "checkbox",
            "label": "Show Sidebar",
            "default": "1"
        },
        "footer_copyright": {
            "type": "text",
            "label": "Footer Copyright Text",
            "default": ""
        }
    },
    "css_class_mapping": {
        "cls_widget": "widget mb-4",
        "cls_title": "h6 fw-bold mb-3 pb-2 border-bottom",
        "cls_btn_primary": "btn btn-primary",
        "cls_pager_list": "pagination justify-content-center"
    }
}

Metadata Fields

name

Type: string | Required: yes

Human-readable theme name. Displayed in the admin Themes gallery and the active theme indicator.

version

Type: string (semver) | Required: yes

Current theme version. Compared against update_url response for upgrade detection.

min_pubvana_version / max_pubvana_version

Type: string | Required: yes

Compatibility range. Activation is blocked below min, warning shown above max.

update_url

Type: string (URL) | Required: yes

Same contract as plugin update_url: POST { "folder": "...", "version": "..." }, expect { "has_update": bool, "latest_version": "...", "download_url": "..." }.

author, author_url, support_url

Type: string | Required: yes

Author name, author website URL, support/contact URL.

description

Type: string | Required: yes

One to three sentences. Shown in the Themes gallery.

screenshot

Type: string | Required: no (recommended)

Filename of the preview image relative to the theme root. Standard: "screenshot.png".

Framework Declarations

Informational — not enforced by the engine, but displayed in the admin UI and used by marketplace filters.

Field Example values
css_framework "Bootstrap", "Tailwind", "Bulma", "None"
css_frame_ver "5.x", "3.x"
icon_pack "FontAwesome", "Bootstrap Icons", "None"
icon_pack_ver "6.x", "5.x"
js_framework "Bootstrap", "Alpine.js", "Vanilla"
js_framework_ver "5.x", "3.x"

widget_areas Object

Declares the named widget slots this theme supports. Keys are slugs (used in {! widget_area "slug" !}); values are human-readable labels shown in the admin Widgets UI.

"widget_areas": {
    "sidebar":        "Main Sidebar",
    "footer-1":       "Footer Column 1",
    "footer-2":       "Footer Column 2",
    "footer-3":       "Footer Column 3",
    "before-content": "Before Content"
}

On theme activation, these areas are synced to the widget_areas database table. Widgets assigned to areas that no longer exist in the new theme's manifest are orphaned (not deleted, but not rendered).

options Object

Declares configurable theme options. The admin panel auto-generates a settings form from this schema. Values are stored per-theme in the theme_options table and accessible in templates as {{ theme_options.option_key }}.

Option Types

checkbox

"show_sidebar": {
    "type": "checkbox",
    "label": "Show Sidebar",
    "default": "1"
}

Value is "1" (checked) or "0" (unchecked). Access: {{ theme_options.show_sidebar }} or {% if theme_options.show_sidebar %}.

text

"footer_copyright": {
    "type": "text",
    "label": "Footer Copyright Text",
    "default": "© 2024 My Site"
}

select

"layout": {
    "type": "select",
    "label": "Layout",
    "default": "sidebar-right",
    "choices": {
        "sidebar-right": "Sidebar Right",
        "sidebar-left":  "Sidebar Left",
        "full-width":    "Full Width"
    }
}

textarea

"custom_css": {
    "type": "textarea",
    "label": "Custom CSS",
    "default": ""
}

css_class_mapping Object

The most important and most extensive part of theme_info.json. Maps 100+ semantic keys to actual CSS class strings. Widgets and plugin templates use {{ cls.key_name }} instead of hardcoded CSS classes. This means widgets work across any CSS framework without modification.

Key Categories

Widget shell

"cls_widget": "widget mb-4",
"cls_title":  "h6 fw-bold mb-3 pb-2 border-bottom",
"cls_widget_body": "widget-body"

Buttons

"cls_btn_primary":   "btn btn-primary",
"cls_btn_secondary": "btn btn-secondary",
"cls_btn_success":   "btn btn-success",
"cls_btn_danger":    "btn btn-danger",
"cls_btn_sm":        "btn btn-sm",
"cls_btn_lg":        "btn btn-lg"

Layout

"cls_container":     "container",
"cls_row":           "row",
"cls_col":           "col",
"cls_col_auto":      "col-auto"

Cards

"cls_card":          "card",
"cls_card_body":     "card-body",
"cls_card_title":    "card-title",
"cls_card_text":     "card-text",
"cls_card_img_top":  "card-img-top"

Typography

"cls_h1": "h1",
"cls_h2": "h2",
"cls_lead": "lead",
"cls_text_muted": "text-muted",
"cls_text_center": "text-center"

Lists

"cls_list_group":       "list-group",
"cls_list_group_item":  "list-group-item",
"cls_list_unstyled":    "list-unstyled"

Forms

"cls_form_control":  "form-control",
"cls_form_label":    "form-label",
"cls_form_select":   "form-select",
"cls_input_group":   "input-group"

Alerts

"cls_alert_success": "alert alert-success",
"cls_alert_danger":  "alert alert-danger",
"cls_alert_warning": "alert alert-warning",
"cls_alert_info":    "alert alert-info"

Pagination

"cls_pager_list": "pagination justify-content-center",
"cls_pager_item": "page-item",
"cls_pager_link": "page-link"

Navigation / Breadcrumbs

"cls_nav":           "nav",
"cls_nav_item":      "nav-item",
"cls_nav_link":      "nav-link",
"cls_breadcrumb":    "breadcrumb",
"cls_breadcrumb_item": "breadcrumb-item"

Badges

"cls_badge":         "badge",
"cls_badge_primary": "badge bg-primary",
"cls_badge_secondary":"badge bg-secondary"

The full mapping in the Default theme includes 100+ keys. Define all keys that any widget or plugin public template might reference. For keys you do not need, map them to an empty string "" or a safe neutral class.