How to Adjust SmartAdmin

This page tells you how to change the look and the templates of SmartAdmin in a project.

Rule: Do not edit the files of the theme in your project. The theme is a git submodule. An update of the theme removes your changes, and a change in the submodule makes the update difficult.

Use the procedures below. They keep all your changes in the project.

You want to change Use
Colors, fonts, sizes, spacing The CSS file of the project
The CSS of one plugin page The CSS file of the plugin
The logo The logo
The sign-in, registration, or password recovery page System templates
The content of the header, the menu, the footer, or <head> Theme events
The menu items The menu
A DGS list or form template DGS templates
The HTML of a HUI component HUI templates
The layout (main.phtml, header.phtml) Your own theme

Change the look with CSS

head.phtml of the theme loads the file <http_base>static/css/styles.css after the CSS files of the theme. Thus a rule in this file overrides a rule of the theme with the same selector.

  1. Make the file static/css/styles.css in the web root of the application.
  2. Write the rules that you want to change.
  3. Change the js_version setting. The browser then loads the new file.

Example: change the color of the header and of the primary button.

/* static/css/styles.css */

#header {
    background: #1f3a5f;
}

.btn-primary {
    background-color: #1f3a5f;
    border-color: #17304f;
}

/* Your own blocks use the b-, e-, m- prefixes */
.b-invoice-summary {
    padding: 16px;
}

.b-invoice-summary .e-total {
    font-weight: bold;
}

.b-invoice-summary .e-total.m-overdue {
    color: #a90329;
}

Rules for CSS:

  • Use a selector that is the same as the selector of the theme, or more specific. Do not use !important if a more specific selector does the work.
  • Find the selector of the theme with the developer tools of the browser. The rules of the admin interface are in css/main.css. The rules of DGS lists and forms are in css/db.css.
  • For your own elements, use class names with the prefixes b- (block), e- (element), and m- (modifier). See the Theme package.
  • Do not change the rules of Bootstrap classes (.row, .col-*, .form-control) for all pages. Limit the rule to your block: .b-invoice-summary .form-control { ... }.
  • Put rules for print in static/css/print.css.

CSS for one plugin

Put CSS that only one plugin uses in the static/css directory of the plugin. Register the file in the plugin method:

$this->includeStatic('css/invoices.css');

The theme loads registered files after styles.css. Thus the plugin file can override the theme and the project file.

The theme shows <http_base>static/images/logo.png in the header. To change the logo, replace this file in the project.

To use a different URL or different HTML, add a listener for ITheme::EVENT_THEME_ON_PREPARE_LOGO:

use Festi\Theme\ITheme;
use Festi\Theme\Event\ThemeEvent;

$this->addEventListener(
    ITheme::EVENT_THEME_ON_PREPARE_LOGO,
    function (ThemeEvent &$event) {
        $target = &$event->getTarget();
        $target['logo'] = '/static/images/logo-dark.svg';
        $target['link'] = '/dashboard/';
    }
);

The sign-in page shows the image from the logo_url setting.

Replace a system template

The Jimbo system plugin renders the sign-in pages from these templates of the theme:

  • signin.php
  • signup.phtml
  • forgot_password.phtml

When a plugin renders a template that is not in its own templates directory, the framework looks in the templates directory of the project before it looks in the theme. See Templates.

To replace a system template:

  1. Copy the template from themes/<theme name>/templates/ to <project root>/templates/. Keep the file name.
  2. Change the copy.
<project root>/
|-- templates/
|   `-- signin.php              your template, the framework uses it
`-- themes/
    `-- dashboard/
        `-- templates/
            `-- signin.php      the template of the theme, not changed

In these templates $this is the Jimbo plugin. Keep the names of the form fields (login, password) and the hidden fields. The plugin reads them.

signin.php reads the settings logo_url, enable_rememberme, enable_forgot_password, and enable_signup. Keep these checks in your copy, or the settings have no effect.

Note: This procedure works only for templates that a plugin renders and does not have in its own templates directory. It does not work for the layout templates (main.phtml, head.phtml, header.phtml). The theme object renders them only from the templates directory of the theme.

Add content to the layout

The theme dispatches an event at each location where a plugin can add content. Add a listener in the init.php of your plugin. The listener returns HTML.

Location Event
End of <head> ITheme::EVENT_THEME_HEAD_BOTTOM
Header, next to the logo ITheme::EVENT_THEME_HEADER_USER_ACTIVITY
Header, projects list ITheme::EVENT_THEME_PROJECTS_LIST
Header, right side ITheme::EVENT_THEME_FETCH_HEADER_ELEMENT (target position is right)
Footer ITheme::EVENT_THEME_FETCH_FOOTER
User name in the left panel ITheme::EVENT_THEME_TITLE
Link of the user name ITheme::EVENT_THEME_USER_INFO_URL

In init.php, $this is the Core object. Get a plugin instance in the listener, not in init.php.

Example: add a button to the right side of the header.

// plugins/Help/init.php
use Festi\Theme\ITheme;

$this->addEventListener(
    ITheme::EVENT_THEME_FETCH_HEADER_ELEMENT,
    function (FestiEvent &$event) {
        $plugin = Core::getInstance()->getPluginInstance('Help');

        return $plugin->fetch('header_button.phtml');
    }
);

Example: add a snippet at the end of <head>.

$this->addEventListener(
    ITheme::EVENT_THEME_HEAD_BOTTOM,
    function (FestiEvent &$event) {
        return '<meta name="theme-color" content="#1f3a5f">';
    }
);

Change the menu

  • To add, remove, or change menu items, add a listener for MenuEvent::EVENT_ON_PREPARE_MENU_ITEMS. The listener gets the items by reference.
  • To replace the full menu, add a listener for ITheme::EVENT_THEME_FETCH_MENU and return the HTML of the menu. The left panel and the mobile menu bar then show this HTML.

See the Theme package.

Replace a DGS template

The Data Grid Store looks for its templates in the templates directory of the theme before it looks in the Theme package. SmartAdmin does not contain DGS templates. Thus the DGS uses the default templates of the Theme package.

To replace one DGS template for the project, use your own theme (see below) and put the template in it with the same relative path, for example templates/store/list.phtml.

For a change that only one store needs, use the DGS methods. They need no change of a theme. See DGS templates.

Replace the template of a HUI component

A HUI component looks for its template (for example ui/button.phtml) with the template lookup of the plugin that makes it. It then uses the default template of the Theme package.

To change a component for the full project, put the template in <project root>/templates/ui/. Keep the file name. To change a component for one plugin only, put the template in plugins/<Name>/templates/ui/.

<project root>/
`-- templates/
    `-- ui/
        `-- button.phtml        your template for $this->ui->button()

Make your own theme from SmartAdmin

If you must change the layout templates (main.phtml, head.phtml, header.phtml, left_panel.phtml), do not edit the submodule.

  1. Make a fork of the SmartAdmin repository for your project.
  2. Add your fork as the theme submodule.
  3. Change the layout templates in your fork.
  4. Merge the changes of SmartAdmin into your fork regularly.

Use this procedure only when CSS, events, and system templates are not sufficient. A fork needs maintenance.

Checks after a change

  1. Change the js_version setting.
  2. Open a page with a DGS list and open its "add" form. Make sure that the list, the dialog, and the form show correctly.
  3. Open the sign-in page in a window where you are not signed in.
  4. Do the checks again with a narrow browser window (mobile layout).