MSC Theme

From Webmin Documentation
Jump to: navigation, search
Webmin development

Creating Overlay Themes
Creating Webmin Themes
MSC Theme
The Webmin API

Module Development
Advanced Module Development
Job Scheduling
Translating Webmin
Development Ideas

This chapter explains the inner workings of Webmin's default theme, which makes use of almost all of the features available to theme developers.

Theme design and graphics

This new theme has been the default in Webmin since 0.92, although the old ‘classic' Webmin look and feel is still available. It makes use of practically all theme-related features, such as alternate graphics, CGI program replacement and a library that replaces the standard header and footer functions. For these reasons it is a good one to look at if you are planning on writing your own theme.

The mscstyle3 directory that contains the theme has a sub-directory for most of the standard modules, each of which contains an images/icons.gif file. These override the corresponding standard module icons that appear on Webmin's main menu. No other overriding images exist though, such as for icons within modules, meaning that the original images are still used.

The theme directory also contains an images subdirectory under which all of the images used by the theme itself are located. The heading that appears on every page is made up of numerous images, such as those for the category icons, category title letters, shaded background and logout button. Because they are specific to the theme, most do not have any corresponding real image under the top-level images directory to override.

Like all themes must, this one includes a file containing its description that will appear on the Themes page in the Webmin Configuration module. It also includes a config file, which tells the Webmin API to read in and use the functions that it contains to replace the standard header and footer functions. It also contains several lines starting with cs_ that set the table background and heading color. Unlike other simpler hemes, the config file does not need to specify any alternate page text or background colors, as these can be set directly by its theme_header function.

The index.cgi program

Because most of the graphical customization done by this theme occurs in the script, its replacement index.cgi program does not differ much from the standard index.cgi in the top-level Webmin directory. The biggest difference is that it does not output any special index page heading or image – instead, it just gets the list of modules available to the current user with get_available_module_infos and uses it to build a table of icons in the current category. Because the theme's theme_header function also calls this function, the list may already be in the global @msc_modules variable. Theme CGI programs execute in the ‘original' directory instead of the directory they are really in, thus the index.cgi program in the MSC theme can use the line require ‘./';.

It is possible to create quite a different theme just be replacing index.cgi, without the need for a theme's function file. The standard Caldera theme has an index.cgi script that actually generates a frame set, in which the top frame displays categories and modules, and the bottom shows actual pages within modules. It is possible for a theme to include CGI programs that do not override any real program, and are used only as part of the theme's user interface – for example, the index_top.cgi program that the Caldera theme uses to render the top frame. Again, such programs are run in the corresponding real directory, not in the theme's sub-directory.

The MSC theme's index.cgi and scripts all make use of %text and the text function to get messages to display to the user, instead of hard-coding them into the Perl code. All of the messages come from the appropriate file in Webmin's top-level lang directory. If you are creating your own theme that overrides any CGI program or function, the same thing should be done to take advantage of the existing translations into many languages that Webmin already includes.

The theme_header function

The theme_header function in in the mscstyle3 directory effectively replaces the standard header function that almost all Webmin CGI programs call. Unlike the standard header, this one produces HTML for a list of module category icons at the top of most pages, allowing the user to easily switch to a different category. As well, it outputs HTML for a link to, logout and feedback buttons, and the standard links like *Module Index* and Module Config. Finally, HTML is produced that puts the entire rest of the page inside the white table box that you can see on almost every page.

The table of categories is generated by calling get_available_module_infos, checking to see which categories actually exist, reading the file /etc/webmin/webmin.catnames to get alternate names, then displaying an icon and name made up of letter images for each. The theme has images for all of the standard categories, plus a special question-mark image to be used if a non-standard or user-defined category is found. Just generating a fixed table of standard categories would not work, as it is possible that the user only has access to modules in some of them.

Because the category titles may be in a different language that uses characters outside of the standard English alphabet, this theme includes images for every letter with ASCII codes between 32 and 255. Any other theme that uses letter images should do the same, so that it will work in non-English languages as well. For some languages (such as Chinese and Russian), it is impossible to create an image for every single character, due to the thousands that exist. The MSC theme checks the global variable $current_lang_info->{'titles'} and if it is not set produces plain text category labels instead.

When Webmin is in session authentication mode (determined by checking for the $main::session_id variable), a logout image button is added to the top-right corner of every page. However, if normal HTTP authentication is being used this is replaced by a button for switching users, which links to a different CGI program. The old Webmin theme only has these links on the main menu. The code properly checks the $ENV{'SSL_USER'}, $ENV{'LOCAL_USER'}and $ENV{'ANONYMOUS_USER'}environment variables, any of which if set indicates that no logout or switch button should appear.

Similarly every page has a feedback button in the top-right corner as well, unless $ENV{'ANONYMOUS_USER'}is set or the global or per-user configuration indicates that feedback is not allowed. This links to feedback_form.cgi with the current module name as a parameter, so that any feedback sent it automatically associated with the current module. This is a nice idea if you are writing your own theme.

Below the row of category icons are several small tabs, for links like Module Index and Module Config. The theme_header function checks its parameters and $ENV variables to determine which ones to show, just like the standard header function does. The biggest difference is that no Webmin Index link is ever produce, as there is no need for it – the user can return to the module's category by just clicking on the appropriate icon at the top of any page.

Below any tabs comes the page title, supplied to the theme_header function as the first parameter. The MSC theme puts it in a small tab above the page body using only text, unlike the old Webmin theme which renders the title as a series of letter images.

Finally, the theme puts page content output by the CGI after header is called into a large box, by producing HTML tags to start a table. However, this is not done if the global variable $theme_no_table is set – instead, the content will be just part of the page's body. CGI programs that slowly generate progressive output should set this variable, and themes that have their own custom theme_header function should honor it if appropriate. Of course, if your theme doesn't use this kind of table for layout then the variable can be ignored.

The theme_footer function

This function is must simpler, and not very different to the standard footer function from It just prints HTML to close the table started by theme_header (unless $theme_no_table is set), followed by links to previous pages as specified in the parameters. Finally the required </body> and </html> tags are produced to properly end the page. When overriding the footer function in your own theme, make sure that is properly processes all of the parameters, as multiple pairs of return links and titles can be provided. If your theme's main menu categorized modules, any link to / should be replaced with a link like /?cat=$module_info{'category'} so that the current module's category is displayed when such as link is used to return to the main menu. Most themes put an arrow next to each of the return links, but this is not required – yours could just use text links, form buttons or anything that you can think of.

If the last parameter to the footer function is non-zero, it will not produce HTML for the end of the page, and instead only generate the return links. The MSC theme's theme_footer function checks for this if the number of parameters is odd, and does the right thing. Your theme should too, as some Webmin programs depend upon this behavior to get the correct layout.