Learn theming by taking apart Lullabot's 960 Robots

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
You are viewing a wiki page. You are welcome to join the group and then edit it. Be bold!

If you're still struggling to learn Drupal theming, you may be happy to know that Lullabot has released 2 videos detailing how to theme a Drupal site from start to finish. You can download the 960 Robots theme at http://drupal.org/project/ninesixtyrobots and what's more, you can download the complete sample site along with the content types, filler contents and the theme all in one package! (Direct download here)

I have been trying to do hands on theming meetups here in HK, but it hasn't been easy, but I think what Lullabot has provided us is a perfect starting point! Let's install their 960 Robots distribution and pull apart its theme! I'm aiming to use this as our HKDUG Drupal Introduction Session at this year's BarCamp HK. So let's start organizing the info here!

First step - Installation

It should be pretty easy for everyone here. Simply download the 6.89MB zip file, extract it onto your web public folder (eg. public_html/lullabot_robots), create a new database and give one of your db users the rights. Then, in your Firefox, go to http://localhost/lullabot_robots, it'll automatically take you to INSTALL.php, type in your newly created database name, db user's name and password. Drupal should successfully install, you will be surprised to find that the site already comes with lots of contents and a nice looking theme!

Personally, I made a 2nd installation from the same source and gave it a different name. This way I can switch between the original 960 Robots, and my totally fv*ked version in 2 tabs in Firefox, without having to switch themes in Drupal.

Create a new theme

OK, I'm calling my 2nd site 960 Cyborgs. In your themes folder, you should see a ninesixtyrobots folder. That's Lullabot's theme. Go ahead and create a new folder, I named it ninesixtycyborgs. From Lullabot's theme, copy the ninesixtyrobots.info file, paste it into the new folder and rename it to ninesixtycyborgs.info. Open the file, I changed the first 2 lines to:

name = 960 Cyborgs
description = Taking apart the theme for Lullabot's theming video based on the 960 grid system.

Immediately, our theme is already available! Choose it and see what happens? All styling gone! This is actually interesting too. You can see how Drupal handles the outputs by default. (Open firebug, open the head section, you can see that although our .info asked it to pull in

stylesheets[all][] = css/reset.css
stylesheets[all][] = css/960.css
stylesheets[all][] = css/main.css

problem is they don't exist! And Drupal is pulling in from core's /cyborgs/modules/system/defaults.css?H (What does that last "H" do? Anyone?)

If you view source, you can see the order in which Drupal outputs the site by default:

<div id="page">
  <div id="header">
    <div id="logo-title">
    <div id="search-box">
  <div id="container">
    <div id="navigation" class="menu with primary withsecondary">
      <div id="primary">
      <div id="secondary">
    <div id="sidebar-left">
      <div id="block-block-1">
      <div id="block-views-images-block_1">
      <div id="block-views-popular-block">
      <div id="block-block-4">
      <div id="block-block-2">
      <div id="block-block-5">
    <div id="main>
      <div id="main-squeeze">
        <div id="content">
          <div id="content-content">
    <div id="sidebar-right">
      <div id="block-views-nodequeue_1-block">
      <div id="block-menu-devel">
  <div id="footer-wrapper">
    <div id="footer">

OK, now, let's create a new page.tpl.php file. Copy the top part from Robot's page.tpl.php file:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print $language->language ?>" lang="<?php print $language->language ?>" dir="<?php print $language->dir ?>">
<head>
  <title><?php print $head_title; ?></title>
  <?php print $head; ?>
  <?php print $styles; ?>
  <?php print $scripts; ?>
  <script type="text/javascript"><?php /* Needed to avoid Flash of Unstyled Content in IE */ ?> </script>
</head>
  <body>

    <!-- header starts-->
    <div id="header-wrap">
      <div id="header" class="container_16">
        <div id="header-main">
          <h1 id="logo-text"><a href="<?php print $front_page; ?>"><?php print $site_name; ?></a></h1>
          <p id="slogan"><?php print $site_slogan; ?></p>
        </div><!-- navigation -->
        <div id="nav">
          <?php print theme('links', $primary_links, array('class' => 'links primary-links')); ?>
        </div>
        <?php print $search_box; ?>
      </div>
    </div>
    <!-- header ends here -->
   </body>
</html>

Go back and refresh the page. Drupal now sees our new page.tpl.php file and is using it to display our site. Right now, only the header part is rendered.

No styling yet, because although we print $styles in head section to link in the stylesheets that are delcared in the .info file, but the files don't exist yet! So, let's copy the css folder from Robots. Delete everything inside the main.css file! Open your editor of choice and start adding the styles back in one by one. First one is "body":
body {
  font: 11px/165% 'Lucida Grande', Verdana, Helvetica, sans-serif;
  color: #666666;
  margin: 0;
  padding: 0 0 50px 0;
  background: #FBFAE8;
  text-align: center;
}

Refresh, nice!! Not a lot of change but you see the font style already changed. Next is "header-wrap":

#header-wrap {
  / * width: 100%;
  background: #fff url(../images/bg.gif) repeat-x ;
  margin: 0;
  padding: 0; * /
}

Hmm... this whole thing is commented in, I'm not sure why, and the location of bg.gif doesn't make sense... perhaps this was something lullabot did in the process of theming but later abandoned? We'll have to watch the video to find out. Next is "header":

#header {
  position: relative;
  margin: 0 auto;
  height: 222px;
  border-top: 14px solid #5C4B45;
  text-align: left;
}

Interesting... it's already taking shape! Now at this point you should be wondering... "How the f*ck did it limit the width of the header when we didn't declare it in the css above?!" The answer can be easily seen in firebug <div id="header" class="container_16">, and if you look to the right, the width is declared in the 960.css file!

.container_12,
.container_16
{
   margin-left: auto;
margin-right: auto;
    width: 960px;
}

Nice! OK next up is "header-main":

#header-main {
  background: #B3BFBF url(../images/robots.png) no-repeat top right;
  height: 166px;
  position: relative;
  top: 50px;
  border-top: 6px solid #5C4B45;
}

Here, we can see the background color and image, height and top margin applied. Look at the page.tpl.php file, the $site_name and $site_slogan which are inside the "header-main" div is printed at the top left. But because of the top = 50px positioning, our $primary_links and $search_box are being covered! (In your firebug, try "stopping" the top = 50px line and see the entire header move up to reveal the primary links and search box!

Next one is h1 id="logo-text", this is where comparing the original Robots to our Cyborb theme becomes important. Have the 2 tabs side by side and use "option + command + left/right" to switch between them (on Mac of course!) You can see that "h1" is declared in 3 different places in main.css - line 271, 40 and 29. Let's copy them to our main.css file:

#header h1#logo-text {
  margin: 0;
  padding: 0;
}

h1 {
  font-size: 3.7em;
  font-weight: normal;
  letter-spacing: -2px;
}

h1, h2, h3, h4 {
  font: bold 1em/1.5em Georgia, 'Times New Roman', Times, serif;
  color: #53301B;
  padding: 10px 0 7px 10px;
}

Sick!! It's freaking ugly! The font got bigger and styled differently than before, but the color is default aweful!! Well, it is a link, so there's more to it! Look at Robot's a href=... part, ahh... lots of styles for "a" - line 275, 13, 34 in main.css, let's copy them over.
#header h1#logo-text a {
  position: absolute;
  margin: 0;
  padding: 0 5px 0 0;
  font: 48px Georgia, 'Times New Roman', Times, serif;
  font-weight: normal;
  letter-spacing: -1px;
  color: #fff;
  text-decoration: none;

  /* change the values of top and left to adjust the position of the logo*/
  top: 30px;
  left: 40px;
}
#header h1#logo-text a:hover {
  border: none;
}

a:link, a:visited {
  text-decoration: none;
  color: #346199;
}
a:hover {
  border-bottom: 1px dotted #346199;
}

h1 a, h2 a, h3 a, h4 a {
  color: #53301B;
}
h1 a:hover, h2 a:hover h3 a:hover, h4 a:hover {
  border-bottom: 1px dotted #53301B;
}

Beautiful! Now our h1 a $site_name is complete!

The next one gets a bit tougher - the site_slogan: <p id="slogan"><?php print $site_slogan; ?></p> It's there in page.tpl.php, if you open firebug, you see <p id="slogan" />, but no content is in it. So, we know the variable $site_slogan is not returning anything. So, perhaps the slogan isn't defined on the site? Go to your admin/settings/site-information, hey, it's there! But wait, there's more, I noticed that the Robots' site slogan is different everytime I reload, (and I read about it on lullabot's info page. They are using Twitter's API to search for tweets to be used as site slogans! Go to admin/build/themes/settings/ninesixtyrobots. Down at the bottom you can find the "Theme-specific settings", so... where does one put custom PHP codes to overwrite Drupal's default $site_slogan? The answer is template.php. Open Robot's template.php file and search for $site_slogan, you'll find this:

<?php

function ninesixtycyborgs_preprocess_page(&$vars) {
  $use_twitter = theme_get_setting('use_twitter');
  if (is_null($use_twitter)) {
    $use_twitter = 1;
  }
 
  $query = theme_get_setting('twitter_search_term');
  if (is_null($query)) {
    $query = 'lullabot';
  }
  $query = urlencode($query);
   
  if ($use_twitter) {
    $response = drupal_http_request('http://search.twitter.com/search.json?q=' . $query);
    $data = json_decode($response->data);
    $tweet = $data->results[array_rand($data->results)];
    $vars['site_slogan'] = check_plain($tweet->text);
  }
}

To learn more about this, check Drupal's API: http://api.drupal.org/api/function/phptemplate_preprocess_page/6 Remember, we need to change the phptemplate_preprocess_page name from ninesixtyrobots_preprocess_page to ninesixtycyborgs_preprocess_page.

Copy it and paste it into a new template.php in our Cyborgs folder. Refresh. WTF?!@ Well, although we now have the php codes in template to fill in the $site_slogan variable, it's all useless if we didn't include it in our theme settings to begin with!! Go to admin/build/themes/settings/ninesixtycyborgs, see the bottom? We're missing some custom settings that were in the Robots theme! Look at Robot's folder, see that theme-settings.php file? Copy it over to our Cyborgs folder:

<?php

function ninesixtycyborgs_settings($saved_settings) {
  $defaults = array(
    'breadcrumb_delimiter' => ' » ',
    'use_twitter' => 1,
    'twitter_search_term' => 'lullabot',
  );
  $settings = array_merge($defaults, $saved_settings);
 
  $form['breadcrumb_delimiter'] = array(
    '#type' => 'textfield',
    '#title' => t('Breadcrumb delimiter'),
    '#size' => 4,
    '#default_value' => $settings['breadcrumb_delimiter'],
    '#description' => t("Don't forget spaces at either end... if you're into that sort of thing."),
  );
  $form['use_twitter'] = array(
    '#type' => 'checkbox',
    '#title' => t('Use Twitter for site slogan'),
    '#default_value' => $settings['use_twitter'],
    '#description' => t("Choose a random status update using the search term below."),
  );
  $form['twitter_search_term'] = array(
    '#type' => 'textfield',
    '#title' => t('Twitter search term'),
    '#default_value' => $settings['twitter_search_term'],
    '#description' => t("Pull a random tweet from search.twitter.com using this search query."),
  );
 
  return $form;
}

Once again, you have to change the "theme-settings" name from ninesixtyrobots_settngs to ninesixtycyborgs_settings. Now, refresh. YES!! No styling, so it ended up at the top within the header-main div, nothing a little CSS won't fix. Open firebug on both Robot and Cyborg, go to <p id="slogan">, you'll see that Robot has css styling in main.css:

#header p#slogan {
  position: absolute;
  margin: 0;
  padding: 0;
  font-family: Georgia, 'Times New Roman', Times, Serif;
  font-weight: normal;
  font-size: 17px;
  line-height: 1.1em;
  font-style: italic;
  letter-spacing: -.5px;
  color: #fff;
  width: 400px;

  /* change the values of top and left to adjust the position */
  top: 88px;
  left: 40px;
}

Add this to our main.css, refresh the browser, beautiful! Now we're done with <div id="header-main">, next up is <div id="nav">. If you look at page.tpl.php, you'll see <?php print theme('links', $primary_links, array('class' => 'links primary-links')); ?>, and the question should be, how did that theme() function give us the menu items listed inside
<span id="thmr_178" class="thmr_call">
  <ul class="links primary-links"><li class="menu-204 active-trail first active"><a href="/mysite/" title="" class="active">Home</a></li>
  <li class="menu-212"><a href="/mysite/about" title="About Us">About</a></li>
  ...etc...
  <li class="menu-238 last"><a href="/mysite/logout" title="">Log out</a></li>
</ul></span>

By now, you should know the drill, look at the css for the new element on the Robot site, copy & paste the css into the Cyborg site. See the difference made.

AttachmentSize
960_Cyborg_01_default.jpeg367.83 KB
960_Cyborg_02_header.jpeg12.91 KB
960_Cyborg_03_header.jpeg9.14 KB
960_Cyborg_04_header-main.jpeg28.82 KB
960_Cyborg_05_header-main-logo-text.jpeg31.53 KB
960_Cyborg_06_got_slogan.jpeg33.81 KB

DrupalHK

Group categories

HKDUG Vocabulary

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds:

Hot content this week