Skip to content

Tutorial.Theme and Block I.zh_cn

linzongshu edited this page Jul 4, 2013 · 2 revisions

English

主题

在模块设计一章里,我们已经介绍了模块模板的概念,但模块模板实际上只是整个页面的一部分。而其他元素如导航、页眉、页脚以及区块等都需要在页面上呈现,这就需要一个总模板来定义这些元素。在Pi Engine里,总模板及其CSS、JavaScript都独立成一个文件包,也称之为主题,它定义了一个页面的基本布局、样式等,这个主题可以在系统的后台安装并应用。如Pi Engine提供了一个默认的主题 - default,在usr/theme目录下。

主题包必须放在usr/theme目录下,这样它才能被系统检测并安装。一般一个主题包需要包含这个主题所必须的js, css及其他静态文件,当然最重要的就是决定页面布局的phtml文件。

1.1 主题包目录结构

主题包下主要包含如下文件,asset, locale, module, template和config.php,目录的结构如下:

fig5-1

图5-1 主题目录结构

  • asset目录:这个目录包含js, css和图像文件,这些文件在主题安装后将会发布到系统包的www/asset目录下,以theme-{theme name}的目录存在,这样外部就可以访问到这些文件;
  • locale目录:这个目录主要用于语言的本地化,包含一些翻译文件,具体的目录结构将会在本地化一节介绍;
  • module目录:包含了模块的主题文件,在安装后,这些模块的静态文件的优先级将会高于模块本身。如图中的demo就是demo模块的主题文件包,它的asset目录下的文件也将在安装的时候发布到www/asset目录下,并以custom-{theme name}的目录存在;
  • template目录:这个目录下存放phtml文件,用于定义页面的布局;
  • config.php:以数组的形式定义主题的基本信息。

对于一个主题,至少需要包含以下文件:

  • 前台模板:

    • template/layout-front.phtml - 这个文件要定义完整的页头、页脚、BODY、区块和导航;
    • template/layout-simple.phtml - 错误页模板,必须定义页头、页脚和BODY;
    • template/layout-style.phtml - 带有样式的简单内容输出模板;
    • template/layout-content.phtml - 没有样式的简单内容输出模板,用于AJAX页面输出返回值;
  • 后台模板:

    • template/layout-admin.phtml - 后台页面布局模板。
  • 前后台都必须有的模板:

    • template/paginator.phtml - 分页显示模板;
    • template/error-exception.phtml - 错误异常页面模板;
    • template/error-404.phtml - 404页面模板;
    • template/error-denied.phtml - 禁止访问模板;
  • 样式文件:

    • asset/css/style.css - 主要的样式文件;

1.2 创建一个主题

这一节里,我们将结合例子,介绍下主题里每个文件的作用,以及如何定义主题里的文件。

1.2.1 主题配置文件

主题配置文件包含了主题的基本信息,只有定义了这个文件,主题才可以被Pi系统检测到。在安装完主题后,这些基本信息也将会被写入数据库里。现在我们要创建一个名为course的主题,并添加其配置文件,因此我们需要在usr/theme下创建course目录:

usr
|- theme
   |- course
      |- config.php

在config.php里添加如下代码:

路径:usr/theme/course/config.php

Code 5.1.1

<?php
return array(
    'version'       => '1.0.0-beta.1',
    'type'          => 'front',
    'title'         => 'Course Theme',
    'author'        => 'zongshu <[email protected]>',
    'screenshot'    => 'image/screenshot.png',
    'license'       => 'Creative Common License http://creativecommons.org/licenses/by/3.0/',
    'description'   => 'Course theme for Training',
);

其中,version定义了主题当前的版本;

type定义了可获得的主题,字段值可为front, admin和both,默认值为both,在这个例子里,我们只定义前台的主题;

screenshot定义了主题缩略图的路径,一般放在asset/image目录下。

现在在course目录下创建asset/image目录,并随便放一张图在这个目录下,被命名为screenshot.png,进入系统后台的theme页里,就可以看到多了一个可获取的主题:

fig5-2

图5-2 配置可获取的主题

当然,不像模块,单纯完成配置文件就可以安装。现在还需要创建上面提到的必要文件。添加这些文件后,主题就可以安装了。

我们先按上面的列表添加这些空文件,代码的添加将在后面的章节里介绍。由于我们创建的是前台模板,因此添加的文件如下:

fig5-3

图5-3 前台主题必要文件

至此,主题就可以成功安装了。在这个例子里,对于前台样式、导航样式以及分页模板我们不作更改,直接采用default主题里的,因此开发者需要从default主题里将style.css, front.css, menu.css和paginator.phtml复制到course的相应目录里。

1.2.2 添加前台布局模板

有了基本样式,我们就可以完成前台布局模板了。前台的布局主要是在layout-front.phtml文件里实现的,因此这个模板里要有完整的页面信息。

打开layout-front.phtml文件,并添加如下代码:

路径:usr/theme/course/template/layout-front.phtml

Code 5.1.2

<?php
$this->i18nTheme('main');

$this->bootstrap();

$this->css(array(
    $this->assetTheme('css/style.css'),
    $this->assetTheme('css/front.css'),
));
?>
<!DOCTYPE HTML>
<html lang="<?php echo $locale; ?>">
<head>
    <meta charset="<?php echo $charset; ?>">
    <?php echo $this->headTitle(); ?>

</head>

<body id="pi-<?php echo Pi::service('module')->current(); ?>" class="<?php echo $locale; ?>">
    <div class="header clearfix">
        <div class="container clearfix">
                <a href="<?php echo Pi::url('www'); ?>" title="<?php echo $this->escape($sitename); ?>" class="header-logo"><?php echo $this->escape($sitename); ?></a>
        </div>
    </div>

    <div class="global-nav container">

        <!-- Global navigation starts -->
        <?php $navigation = $this->nav('front'); ?>
        <?php if ($navigation) { ?>

            <!-- Global menu starts -->
            <?php $this->css($this->assetTheme('css/menu.css')); ?>
            <div class="menu">
                <?php echo $navigation->menu()->setUlClass('menu-horizontal'); ?>
            </div>
            <!-- Global menu ends -->

            <!-- Global breadcrumbs starts -->
            <?php $breadcrumbs = $navigation->breadcrumbs()->setSeparator('<span class="divider">&gt;</span>')->render(); ?>
            <?php if ($breadcrumbs) { ?>
            <div class="breadcrumb">
                <?php echo $breadcrumbs; ?>
            </div>
            <?php } ?>
            <!-- Global breadcrumbs ends -->

        <?php } ?>
        <!-- Global navigation ends -->
    </div>

    <div class="wrapper">
    <div class="container">

        <!-- Module content starts -->
        <?php if (!empty($content)) { ?>
            <div class="pi-zone-module row-fluid"><?php echo $content; ?></div>
        <?php } ?>
        <!-- Module content ends -->

    </div>
    </div>

    <!-- Footer starts -->
    <div class="footer">
        <div class="horizontal-rule"></div>
        <div class="container">
            <!-- Official statement starts -->
            <a href=""><?php _e('About us'); ?></a>  |
            <a href=""><?php _e('Contact us'); ?></a>  |
            <a href=""><?php _e('Sitemap'); ?></a> <br/>
            &copy; <a href="<?php echo Pi::url('www'); ?>" title="<?php echo $this->escape($sitename); ?>"><?php echo $this->escape($sitename); ?></a> | Theme for training
        </div>

        <!-- Show execution time -->
        <?php $time = microtime(true) - Pi::startTime(); ?>
        <span style="font-size: 80%;" title="<?php _e('Execution time'); ?>"><?php echo $time; ?></span>
        <!-- Show execution time -->

    </div>
    <!-- Footer ends -->

</body>
</html>

在这个文件的开头,调用了三个helper,分别是i18nTheme(), bootstrap()和css(),其中i18nTheme用于载入翻译文件,这里指定采用当前翻译语言的main文件,也就是locale/en/main.csv文件;Pi Engine引入了bootstrap样式库,bootstrap()指定义了引用bootstrap样式文件;css()也是用于引入css文件,它和bootstrap一样,都在会页面生成<link>标签,这样我们就可以在页面里应用已经定义的样式了。

在head和body里,可以看到有类似$locale, $charset的变量,这些变量我们之前都没有提及过,它们就是模板的预定义变量,这些变量由系统生成和赋值,不需要开发者去操作,可以直接在主题模板和模块模板里使用,下面列出了这些预定义变量,它们的值都可以在后台配置:

  • $sitename - 网站名称;
  • $slogan - 网站标语;
  • $adminmail - 管理员的邮箱地址;
  • $locale - 当前系统所使用的语言环境,如en, zh-CN等;
  • $charset - 页面的编码形式,默认为utf8;
  • $timezone_server - 服务器的时区,也就是php.ini里定义的时区;
  • $timezone_system - 系统的时区;
  • $theme, $theme_admin - 系统前后台已经应用的主题。

<head></head>里,设置了当前页面的编码,并调用headTile() helper输出<title></title>标签用于定义页面的名称。

在body标签里定义了页面的整体布局,这部分可包括页头、导航、区块、模块和页脚。这个例子里,我们暂时没有介绍区块的定义,这一部分将在区块一节里介绍。

在页头部分,主要输出预定义变量$sitename,也就是网站的名称;页头之后就是输出导航和面包屑,这里主要完成的功能就是获取导航的数据并生成相应的标签并添加样式,关于导航的原理,将在导航一章中介绍;在layout-front.phtml里,导航后面应该是开始输出页面的布局,在Pi Engine我们定义为区块+模块的布局,下一节介绍区块的时候,我们会重点介绍,因此这里只输出模块部分,模块的内容都通过模块模板生成HTML标签,也就是已经静态化了,内容存在$content变量里,在layout里只需要将其输出即可;最后一部分就是页脚,这部分开发者也可根据自己网站的需求作更改,这里我们对default里的页脚进行了简化,只输出了几个链接及页面载入的时间。

现在我们访问localhost/course/www进入主页就可以看到当前的页面里,原来显示登陆的区块不见了,页脚也发生了变化:

fig5-4

图5-4 course主题

1.2.3 为AJAX添加模板

layout-front.phtml可以让大部分页面显示,但不能用于AJAX页面输出结果,所以我们需要添加一个简单的内容输出页,也就是这里的layout-content.phtml模板。AJAX模板页只需要输出Action里返回的内容,不需要其他HTML标签,因此页面只需要输出$content变量值即可:

路径:usr/theme/course/template/layout-content.phtml

Code 5.1.3

<?php if (!empty($content)) {
    echo $content;
} ?>

另外,error-404.phtml, error-denied.phtml和error-exception.phtml分别用于页面找不到、无权限以及异常时输出错误信息,这部分的代码可参考default主题,这里就不再赘述。

[Tutorial.Theme and Block II](Tutorial.Theme and Block II.zh_cn)

Clone this wiki locally