Themes

Did you creat a beautiful theme for forumify and want to share or sell it on the marketplace? Then you'll have to create a theme.

Dissection of a theme:

my-cool-theme
  /public
  /src/MyCoolTheme.php
  /composer.json

Composer File

Just like plugins, themes are also managed by composer to apply versioning and dependency constraints.

Basic theme composer.json (can be partially generated by running composer init in an empty directory):

/composer.json

{
    "name": "acme-corporation/cool-theme",
    "type": "forumify-theme",
    "autoload": {
        "psr-4": {
            "AcmeCorporation\\": "src/"
        }
    },
    "extra": {
        "forumify-plugin-class": "AcmeCorporation\\CoolTheme"
    }
}
  • name: The vendor and name for your theme, in the form of vendor/name.
  • type: Always forumify-theme for themes.
  • autoload.psr-4: Root PHP namespace definition, using the PSR-4 standard, this should be your vendor name in UpperCamelCase.
  • extra.forumify-plugin-class: Themes are an abstraction of a plugin, so we pick the theme configuration class as plugin class.

Version constraints on forumify aren't as necessary on themes as they are on plugins. A lot less can break with a theme. It is recommended to set at least forumify's major version as a requirement. When forumify updates to a new major, you can always loosen the constraint then. For example if your theme requires at least version 1 of forumify:

/composer.json

{
    // ...
    "requires": {
        "forumify/forumify-platform": "^1.0"
    }
}

Theme Configuration Class

The theme class is used to provide more metadata, declare overridable variables and the location of assets that should be loaded by default.

/src/CoolTheme.php

<?php

namespace AcmeCorporation;

use Forumify\Plugin\AbstractForumifyTheme;
use Forumify\Plugin\PluginMetadata;
use Forumify\Plugin\ThemeConfig;
use Forumify\Plugin\ThemeVar;
use Forumify\Plugin\ThemeVarType;

class CoolTheme extends AbstractForumifyTheme
{
    /**
     * Basic information about your theme.
     */
    public function getPluginMetadata(): PluginMetadata
    {
        return new PluginMetadata(
            'My Cool Theme',
            'ACME Corporation',
            'A very stylish theme that allows users to recolor their header.'
        );
    }

    /**
     * An array of stylesheets that have to be loaded on every page.
     * These files must exist in the /public folder.
     */
    public function getStylesheets(): array
    {
        return ['style.css'];
    }

    /**
     * The theme's configuration which will allow users to override theme parameters.
     * You should add as many variables as possible to allow for maximum customization by the user.
     * Keys are injected into the document as CSS variables
     * Value priority is as follows:
     *      In dark mode: User Config > Dark Default > Default
     *      In light mode: User Config > Default
     */
    public function getThemeConfig(): ThemeConfig
    {
        return new ThemeConfig(
            hasDarkVariant: true,
            vars: [
                new ThemeVar(
                    key: 'c-header-color',
                    label: 'Header Color',
                    type: ThemeVarType::Color,
                    defaultValue: 'orange',
                    defaultDarkValue: 'darkorange'
                ),
            ]
        );
    }
}

Static Resources

Static resources such as CSS stylesheets, images, fonts,... should be placed in the /public directory. When forumify refreshes your theme, for example during initial installation or when updating, it will copy your public directory into the user's /public/themes/<vendor>/<package> directory.

You can also use asset builders to enable sass/scss, the general convention is to place source assets in the /assets directory. The output of your builder can be set to /public. Just be aware that anything outside of the public directory will not be copied into userland!

For example, using the variable we defined in our configuration:

/public/style.css

.header {
    background-color: var(--c-header-color);
}

Testing

To test your theme, we'll symlink it into our development instance of forumify. Assuming the following directory structure:

/forumify
/cool-theme

Modify your instance's (not the theme's!) composer.json:

/forumify/composer.json

{
    // ...
    "repositories": [
        {
            "type": "path",
            "url": "../cool-theme"
        }
    ]
}

Now install your theme using composer:

/forumify

$ composer install acme-corporation/cool-theme

The theme should automatically be added in your instance's admin panel under Settings -> Themes. If you've followed the code samples above, and you activate the theme, you should also be able to change the header menu color straight from the admin panel.

Theme discovery happens during the forumify:plugins:refresh command that is automatically executed after installing or updating dependencies with composer. If it is not automatically added, you can try running the command manually: php bin/console forumify:plugins:refresh.