Chapter 12. An Example Theme

12.1. Image-Free Theme

12.1. Image-Free Theme

This section demonstrates the creation of a theme that is based on a 960-grid, uses no images, yet provides several regions and otherwise participates fully in Perforce Chronicle operations. To create the required components, perform the following steps. For further details about specific topics, refer to the linked documentation.

  1. Create a skeletal theme structure in the folder sites/all/themes:

    imagefree/
        layouts/
        styles/
        views/
            content/
                index/
    
  2. Create the imagefree/theme.ini theme definition file:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    title                       = Image-Free
    version                     = 1.0
    description                 = A theme without images.
    tags                        = example, no-image
     
    [maintainer]
    name                        = Perforce Software
    email                       = support@perforce.com
    url                         = http://www.perforce.com/
     
    [stylesheets]
    all.href                    = styles/styles.css
     
    [menus]
    footer.home.label           = Home
    footer.home.module          = content
    footer.home.controller      = index
    footer.home.action          = index
    footer.home.class           = home
    footer.home.order           = 0
    footer.home.test            = true
     
    footer.login.handler        = user.login-logout
    footer.login.order          = 90
     
    [regions]
    header.1.title              = Site Title
    header.1.type               = widget/text
    header.1.class              = site-title
    header.1.config.text        = The Image-Free Theme
     
    feature.1.title             = Feature Image
    feature.1.type              = widget/image
    feature.1.class             = feature-image
     
    feature.2.title             = Feature
    feature.2.type              = widget/text
    feature.2.class             = feature-text
    feature.2.showTitle         = 1
    feature.2.config.text       = "
    The text for the feature should be added here.<br/><br/>
     
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce congue
    nunc a velit fermentum in tempor diam lacinia. Pellentesque tristique
    dui eget nibh lobortis congue. Maecenas eu bibendum erat. Aliquam
    varius tempor fermentum.
    "
     
    important.1.title           = Important #1
    important.1.type            = widget/text
    important.1.class           = three-column
    important.1.showTitle       = 1
    important.1.config.text     = "
    An important item.<br/><br/>
     
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce congue
    nunc a velit fermentum in tempor diam lacinia. Pellentesque tristique
    dui eget nibh lobortis congue. Maecenas eu bibendum erat. Aliquam
    varius tempor fermentum.
    "
     
    important.2.title           = Important #2
    important.2.type            = widget/text
    important.2.class           = three-column
    important.2.showTitle       = 1
    important.2.config.text     = "
    An important item.<br/><br/>
     
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce congue
    nunc a velit fermentum in tempor diam lacinia. Pellentesque tristique
    dui eget nibh lobortis congue. Maecenas eu bibendum erat. Aliquam
    varius tempor fermentum.
    "
     
    important.3.title           = Important #3
    important.3.type            = widget/text
    important.3.class           = three-column
    important.3.showTitle       = 1
    important.3.config.text     = "
    An important item.<br/><br/>
     
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce congue
    nunc a velit fermentum in tempor diam lacinia. Pellentesque tristique
    dui eget nibh lobortis congue. Maecenas eu bibendum erat. Aliquam
    varius tempor fermentum.
    "

    The first eight lines of this file specify the theme's version, provide a description, list the tags used for filtering themes, and identify the maintainer of the theme.

    The [stylesheets] section includes the CSS stylesheet styles/styles.css in the generated HTML to ensure that the theme is styled correctly.

    The [menus] section specifies the default entries for a menu that is presented in the theme's footer. The footer is identified as footer, and contains two entries: one is a link to the home page and is labelled Home, and the second is a dynamic link that is labelled Login or Logout depending on the user's current authentication state. The Login link specifies an order of 90 to place the link after any other menu items that may be added in the future.

    The [regions] section specifies three logical areas that can be included on pages, identified as header, feature, and important respectively. The configuration for each of these regions specifies the widgets that should be included by default: a text widget labelled Site Title in the header region, an image widget labelled Feature Image and a text widget labelled Feature in the feature region, and three text widgets in the important region with appropriately numbered labels.

    Note how the text widgets define the default text in each case. This provides default content for the widgets to demonstrate the styles in effect.

    At this point, the theme is listed on the Manage Themes page, although it doesn't do anything yet.

    For details about theme configuration details, see Section 11.1, “Configuration File - theme.ini.

  3. Create the imagefree/layouts/default-layout.phtml view script:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    <?= $this->doctype() ?>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <?= $this->headTitle() ?>
    <?= $this->dojo() ?>
    <?= $this->headScript() ?>
    <?= $this->headLink() ?>
    <?= $this->headStyle() ?>
    </head>
     
    <body class="claro
     <?=$this->layout()->getLayout()?>
     <?=$this->request()->getModuleName()?>-module
     <?=$this->request()->getControllerName()?>-controller
     <?=$this->request()->getActionName()?>-action">
    <?=$this->toolbar()?>
    <?=$this->notifications()?>
     
    <div id="header"><div class="container">
    <?= $this->region('header') ?>
    </div></div>
     
    <div id="nav"><div class="container">
    <?= $this->menu('primary', array('maxDepth' => 0)); ?>
    </div></div>
     
    <div id="main"><div class="container">
    <?= $this->layout()->content ?><br class="clear" />
    </div></div>
     
    <div id="footer"><div class="container">
    <?  if (P4Cms_Menu::exists('footer')):
            $menu = P4Cms_Menu::fetch('footer');
            echo $this->menu()->renderMenu(
                $menu->getExpandedContainer(), array('maxDepth' => 0)
            );
        endif;
    ?></div></div>
     
    </body></html>

    default-layout.phtml is a view script. It defines the overall structure for pages using this layout.

    Within the layout file are PHP commands, which are surrounded by <? and ?> tag markers. The tag marker <?= is a shortcut that emits the value of the PHP variable or command within the tag.

    The first 18 lines are common to most themes. They setup the markup to use the correct document type, provide a page title, includes the Dojo Toolkit, any required Javascript and CSS files, plus any required link tags. The body tag provides a number of CSS classes to assist in customizing the presentation for any activity. Finally, the Chronicle toolbar and notifications facilities are included.

    [Warning] Warning:
    If lines 17 and 18 are removed or damaged, interaction with the Chronicle management interface could be significantly compromised.

    The remaining lines are organized into groups which provide the markup respectively for the header, top navigation, page content, and footer. The header region and all of its widgets are generated on line 21. The top navigation is provided by lines 24-31. Note the PHP commands that test for the existence of the menu, which is an important consideration when menus can be removed through the management interface. The page content is provided by line 34. The footer navigation is provided by lines 37-44, using code similar to the top navigation.

    For more details about layouts, see Section 11.3, “Layouts”, or about view scripts, see Section 11.4, “View Scripts”.

  4. Create the imagefree/views/content/index/index.phtml view script:

    1
    2
    3
    <?= $this->region('feature') ?>
     
    <?= $this->region('important') ?>

    index.phtml is a view script. It provides the default markup for the home page of your site. The PHP code renders the two regions feature and important, including the widgets defined in the theme.ini presented in step 2.

    For more details about view scripts, see Section 11.4, “View Scripts”.

  5. Create the imagefree/views/content/index/view.phtml view script:

    1
    2
    3
    4
    5
    6
    7
    <div class="three-column-2">
    <?= $this->contentEntry($this->entry, $this->entryOptions) ?>
    </div>
     
    <div class="three-column">
    <?= $this->region('sidebar') ?>
    </div>

    view.phtml is a view script. It provides the default markup for content. The first three lines render the content entry. The last three lines render a region named sidebar.

    For more details about view scripts, see Section 11.4, “View Scripts”.

  6. Create the imagefree/styles/styles.css CSS file:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    body {
        background-color: #f4f2f3;
        font-family: Arial, Helvetica, sans-serif !important;
        font-size: 14px;
        color: #3d3d3d;
        margin: 0;
        padding: 0;
    }
     
    * {
        margin: 0;
        padding: 0;
    }
     
    img {
        border: none;
        margin: 0;
        padding: 0;
        vertical-align: text-bottom;
    }
     
    a {
        color: #2753a2;
    }
    a:hover {
        color: black;
    }
     
    p,
    .content-element-body {
        font-size: 14px;
        line-height: 19px;
        color: #3d3d3d;
        padding: 4px 0 6px 0;
    }
     
    h1, h2, h3, h4, h5 {
        padding: 6px 0 5px 0;
    }
     
    .content-element, .content-entry {
        margin: 0;
        padding: 0;
    }
    .content-element-title,
    .content-entry-type-basic-page .content-element-title {
        font-size: 21px;
        line-height: 19px;
        padding: 6px 0 9px 0;
        font-weight: bold;
        color: #3d3d3d;
        margin: 0;
    }
     
    .clear {
        clear: both;
    }
     
    /* Container Styles
    ------------------------------------------------*/
     
    #header {
        background: #4e5661;
        height: 88px;
    }
     
    #nav {
        background-color: #404852;
        height: 31px;
    }
     
    #main {
        padding: 10px 0;
    }
     
    #footer {
        clear: both;
        background: #404852;
        font-size: 12px;
        margin-top: 10px;
        height: 29px;
    }
     
    .container {
        margin: 0 auto;
        width: 960px;
    }
     
    /* Styles
    ------------------------------------------------*/
     
    .logo {
        padding: 25px 0 0 10px;
    }
     
    /* Nav */
     
    ul.navigation {
        list-style: none;
        padding: 5px 0 0 0;
    }
     
    ul.navigation li {
        float: left;
        padding: 0;
        font-size: 14px;
    }
    #footer ul.navigation li {
        font-size: 12px;
    }
     
    ul.navigation li a {
        color: white;
        text-decoration: none;
        padding: 7px 10px;
    }
     
    ul.navigation li a:hover {
        background: #2f353c;
    }
     
    /* Column Styles */
     
    .one-column {
        float: left;
        padding: 5px 10px;
        margin: 5px 0;
        width: 940px;
    }
     
    .two-column,
    .two-column.dijitContentPane {
        float: left;
        padding: 5px 10px;
        margin: 5px 0;
        width: 460px;
    }
     
    .three-column,
    .three-column.dijitContentPane {
        float: left;
        padding: 5px 10px;
        margin: 5px 0;
        width: 300px;
    }
     
    .three-column-2,   /* 2 columns wide - using 3 column measurements */
    .three-column-2.dijitContentPane {
        float: left;
        padding: 5px 10px;
        margin: 5px 0;
        width: 620px;
    }
     
    .four-column,
    .four-column.dijitContentPane {
        float: left;
        padding: 5px 10px;
        margin: 5px 0;
        width: 220px;
    }
     
    .four-column-3,   /* 3 columns wide - using 4 column measurements */
    .four-column-3.dijitContentPane {
        float: left;
        padding: 5px 10px;
        margin: 5px 0;
        width: 700px;
    }
     
    /* Other Page Styles */
     
    hr {
        clear: both;
        background: #cfcfd1;
        border: none;
        display: block;
        margin: 0;
        padding: 15px 0;
        height: 1px;
        font-size: inherit;
    }
     
    .callout {
        background: white;
    }
     
    ul {
        list-style: outside;
        padding: 5px 0 7px 15px;
    }
     
    ul.links {
        list-style: none inside;
        padding: 5px 0 7px 0;
    }
     
    ul li {
        padding: 2px 0 4px 0;
    }
     
    /* Regions & Widgets */
     
    #region-feature,
    #region-important {
        overflow: hidden;
        float: left;
        width: 960px;
    }
    #region-feature {
        border-bottom: 1px solid #cfcfd1;
        margin-bottom: 10px;
        padding-bottom: 9px;
    }
     
    #region-header .widget-container {
        float: left;
        padding: 25px 0 0 10px;
        overflow: inherit;
    }
     
    #region-header .site-title {
        float: left;
        color: #e4e4e4;
        font-size: 24px;
        font-weight: bold;
        padding-top: 30px;
    }
    #region-header .layout-title .widget-content {
        text-align: right;
    }
     
    #region-feature .feature-image {
        float: left;
        min-width: 460px;
        min-height: 100px;
    }
    #region-feature .feature-image .widget-content {
        text-align: right;
    }
     
    #region-feature .widget-title,
    #region-important .widget-title {
        color: #3d3d3d;
        padding: 4px 0 8px 0;
        font-size: 19px;
        font-weight: bold;
        line-height: 19px;
    }
     
    #region-feature .widget-widget-text,
    #region-important .widget-widget-text,
    #region-sidebar .widget-content {
        color: #3d3d3d;
        font-size: 14px;
        line-height: 19px;
        padding: 0;
    }

    These CSS classes are inserted into your theme's output by Chronicle due to the [stylesheets] section on lines 10-11 of imagefree/theme.ini above.

    These styles make it fairly easy to construct one to four column layouts based on a 960 pixel grid, similar to the 960 Grid System.

    For more details about resources, see Section 11.2, “Resources”.

  7. Try the new theme!

    You now have a functional theme that you can enable in Chronicle by performing the following steps:

    1. Log into your instance of Chronicle.
    2. To enable the imagefree theme, follow the instructions in Section 19.1, “Applying Themes”.
    3. Click Back to Website.

    Congratulations! You have successfully created your first theme for Chronicle.

Perforce Chronicle - Release: 2012.2/486814