The theme displayed on your Drupal site is the visual appearance of the site. The theme files, or template files as it's often called, control the placement of the elements; mainly regions and blocks, for the purpose of presenting the content and interactivity of a website. How well a theme is designed and implemented is, therefore, largely responsible for the first impression made by those who visit your site. Themes are the most visible, and arguably the most influential, element of your Drupal site.
While the default Drupal distribution includes a set of themes that will prove sufficient for some users; for the vast majority that simply is not the case. This style guide is for those with the desire to do more; whether it be to customize a theme, create a sub-theme or to build your own themes.
<?php /** * @file * Default theme implementation to display a single Drupal page. * * The doctype, html, head and body tags are not in this template. Instead they * can be found in the html.tpl.php template in this directory. * * Available variables: * * General utility variables: * - $base_path: The base URL path of the Drupal installation. At the very * least, this will always default to /. * - $directory: The directory the template is located in, e.g. modules/system * or themes/bartik. * - $is_front: TRUE if the current page is the front page. * - $logged_in: TRUE if the user is registered and signed in. * - $is_admin: TRUE if the user has permission to access administration pages. * * Site identity: * - $front_page: The URL of the front page. Use this instead of $base_path, * when linking to the front page. This includes the language domain or * prefix. * - $logo: The path to the logo image, as defined in theme configuration. * - $site_name: The name of the site, empty when display has been disabled * in theme settings. * - $site_slogan: The slogan of the site, empty when display has been disabled * in theme settings. * * Navigation: * - $main_menu (array): An array containing the Main menu links for the * site, if they have been configured. * - $secondary_menu (array): An array containing the Secondary menu links for * the site, if they have been configured. * - $breadcrumb: The breadcrumb trail for the current page. * * Page content (in order of occurrence in the default page.tpl.php): * - $title_prefix (array): An array containing additional output populated by * modules, intended to be displayed in front of the main title tag that * appears in the template. * - $title: The page title, for use in the actual HTML content. * - $title_suffix (array): An array containing additional output populated by * modules, intended to be displayed after the main title tag that appears in * the template. * - $messages: HTML for status and error messages. Should be displayed * prominently. * - $tabs (array): Tabs linking to any sub-pages beneath the current page * (e.g., the view and edit tabs when displaying a node). * - $action_links (array): Actions local to the page, such as 'Add menu' on the * menu administration interface. * - $feed_icons: A string of all feed icons for the current page. * - $node: The node object, if there is an automatically-loaded node * associated with the page, and the node ID is the second argument * in the page's path (e.g. node/12345 and node/12345/revisions, but not * comment/reply/12345). * * Regions: * - $page['help']: Dynamic help text, mostly for admin pages. * - $page['highlighted']: Items for the highlighted content region. * - $page['content']: The main content of the current page. * - $page['sidebar_first']: Items for the first sidebar. * - $page['sidebar_second']: Items for the second sidebar. * - $page['header']: Items for the header region. * - $page['footer']: Items for the footer region. * * @see template_preprocess() * @see template_preprocess_page() * @see template_process() * @see html.tpl.php * * @ingroup themeable */ ?> <div id="page-wrapper"><div id="page"> <div id="header"><div class="section clearfix"> <?php if ($logo): ?> <a href="/%3C?php_print_%24front_page%3B_%3F%3E" title="<?php print t('Home'); ?>" rel="home" id="logo"> <img src="/%3C?php_print_%24logo%3B_%3F%3E" alt="<?php print t('Home'); ?>" /> </a> <?php endif; ?> <?php if ($site_name || $site_slogan): ?> <div id="name-and-slogan"> <?php if ($site_name): ?> <?php if ($title): ?> <div id="site-name"><strong> <a href="/%3C?php_print_%24front_page%3B_%3F%3E" title="<?php print t('Home'); ?>" rel="home"><span><?php print $site_name; ?></span></a> </strong></div> <?php else: /* Use h1 when the content title is empty */ ?> <h1 id="site-name"> <a href="/%3C?php_print_%24front_page%3B_%3F%3E" title="<?php print t('Home'); ?>" rel="home"><span><?php print $site_name; ?></span></a> </h1> <?php endif; ?> <?php endif; ?> <?php if ($site_slogan): ?> <div id="site-slogan"><?php print $site_slogan; ?></div> <?php endif; ?> </div> <!-- /#name-and-slogan --> <?php endif; ?> <?php print render($page['header']); ?> </div></div> <!-- /.section, /#header --> <?php if ($main_menu || $secondary_menu): ?> <div id="navigation"><div class="section"> <?php print theme('links__system_main_menu', array('links' => $main_menu, 'attributes' => array('id' => 'main-menu', 'class' => array('links', 'inline', 'clearfix')), 'heading' => t('Main menu'))); ?> <?php print theme('links__system_secondary_menu', array('links' => $secondary_menu, 'attributes' => array('id' => 'secondary-menu', 'class' => array('links', 'inline', 'clearfix')), 'heading' => t('Secondary menu'))); ?> </div></div> <!-- /.section, /#navigation --> <?php endif; ?> <?php if ($breadcrumb): ?> <div id="breadcrumb"><?php print $breadcrumb; ?></div> <?php endif; ?> <?php print $messages; ?> <div id="main-wrapper"><div id="main" class="clearfix"> <div id="content" class="column"><div class="section"> <?php if ($page['highlighted']): ?><div id="highlighted"><?php print render($page['highlighted']); ?></div><?php endif; ?> <a id="main-content"></a> <?php print render($title_prefix); ?> <?php if ($title): ?><h1 class="title" id="page-title"><?php print $title; ?></h1><?php endif; ?> <?php print render($title_suffix); ?> <?php if ($tabs): ?><div class="tabs"><?php print render($tabs); ?></div><?php endif; ?> <?php print render($page['help']); ?> <?php if ($action_links): ?><ul class="action-links"><?php print render($action_links); ?></ul><?php endif; ?> <?php print render($page['content']); ?> <?php print $feed_icons; ?> </div></div> <!-- /.section, /#content --> <?php if ($page['sidebar_first']): ?> <div id="sidebar-first" class="column sidebar"><div class="section"> <?php print render($page['sidebar_first']); ?> </div></div> <!-- /.section, /#sidebar-first --> <?php endif; ?> <?php if ($page['sidebar_second']): ?> <div id="sidebar-second" class="column sidebar"><div class="section"> <?php print render($page['sidebar_second']); ?> </div></div> <!-- /.section, /#sidebar-second --> <?php endif; ?> </div></div> <!-- /#main, /#main-wrapper --> <div id="footer"><div class="section"> <?php print render($page['footer']); ?> </div></div> <!-- /.section, /#footer --> </div></div> <!-- /#page, /#page-wrapper -->
Using Bartik as an example a .info file would look like this:
name = Bartik description = A flexible, recolorable theme with many regions. package = Core version = VERSION core = 7.x stylesheets[all][] = css/layout.css stylesheets[all][] = css/style.css stylesheets[all][] = css/colors.css stylesheets[print][] = css/print.css regions[header] = Header regions[help] = Help regions[page_top] = Page top regions[page_bottom] = Page bottom regions[highlighted] = Highlighted regions[featured] = Featured regions[content] = Content regions[sidebar_first] = Sidebar first regions[sidebar_second] = Sidebar second regions[triptych_first] = Triptych first regions[triptych_middle] = Triptych middle regions[triptych_last] = Triptych last regions[footer_firstcolumn] = Footer first column regions[footer_secondcolumn] = Footer second column regions[footer_thirdcolumn] = Footer third column regions[footer_fourthcolumn] = Footer fourth column regions[footer] = Footer settings[shortcut_module_link] = 0
* In theory every module output has a template file. Use the necessary templates files that will get the job done for your site. If you would like to determine what template files are available the Devel module with theme developer is a great asset for this purpose. Make sure you also include the required simplehtmldom to avoid conflict issues.
Get up and running fast by letting an existing theme do most of the heavy lifting for you. Instead of creating a new theme from a blank canvas, you can create a sub-theme, that is esentially a new theme that uses part of the files, styles, and templates of it's parent theme; until overridden. For many, designing from a base theme is a painless way to create a new theme.
The approach to sub-themes will have you searching for an existing theme that meet part of your needs; then you simply create a sub-theme based on that theme. Once you have created the sub-theme you can modify it to fit your needs. To make this approach even more attractive, there are themes that are specifically intended for use as the starting point for sub-themes.
As previously stated; the easiest way to get up and running without the headache of starting from scratch is to use a theme and create a sub-theme from there only overriding the functionality that best suits your website. There are over 1,500 Drupal themes to choose from (at the time of writing) but the following themes are a few that we would recommend.
Many of these themes serve a different purpose for a specific use-case install and customize the theme that best handles your situation.
If you decide to creating your own theme a nice file to have will consists of a reset.css file. The goal of a reset stylesheet is to reduce browser inconsistencies in things like default line heights, margins and font sizes of headings, and so on. A good example provided below is the reset by Eric Meyer. Eric Meyer's CSS reset does not have any colours which leaves most of the styling up to the designer. The CSS reset stylesheet looks like this:
/* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 License: none (public domain) */ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } body { line-height: 1; } ol, ul { list-style: none; } blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } table { border-collapse: collapse; border-spacing: 0; }
You can add this to your style.css file or, even better, create a reset.css file and have your .info file load the file.
7 Well Designed Drupal Themes You Can Install Now
Theming Drupal 6 and 7
Standard Drupal core styles and classes
Overriding themable output