-
Notifications
You must be signed in to change notification settings - Fork 115
Dev.Theme Structure
Introduction
File structure
Layout templates
Introduction of some useful view helpers
Predefine variables
Theme is used to define the layout, interaction and css of your site. Pi allows you to create different themes for different modules or Pi application itself. Users can create a theme package and put it into the usr/theme
directory where themes can be detected. Theme packages mainly contain several front files such as js
, css
, phtml
, etc. These files are packed in different folders. In this guide, we will introduce how to create a theme package and how to use helpers in Pi and Zend library to achieve your tasks.
The structure of this guide is organized as follows:
- Section I introduces the file structure of theme package;
- Section II introduces the usage of helpers packed in Pi library;
- Section III lists the predefine variables of Pi.
The theme
folder is consists of a series of folders, such as asset
, locale
, module
, template
and config.php
. The structure is list as follows:
theme
default {theme package name}
asset
css
image
js
locale
en
module
demo {module theme package name}
asset
template
template
{phtml files}
config.php
-
asset
- contains js, css and image files which will be published toPi/www
folder when installs, these files will override static files of modules. -
locale
- contains translation files. -
module
- contains theme packages for modules, files in these themes will also override that of module when installs.-
demo
- containsasset
andtemplate
folders, it is the theme for modules.
-
-
template
- containsphtml
files for displaying layout. These files mainly include HTML tags. -
config.php
- defines the details of the theme by array.
NOTE: This is a complete structure of a theme package, a theme set at least should includes following files:
- Template files required for front:
-
template/layout-front.phtml
- complete layout template: header, footer, body, blocks, navigation; -
template/layout-simple.phtml
- error page layout: header, footer, body; -
template/layout-style.phtml
- content with stylesheets; -
template/layout-content.phtml
- raw content without stylesheets.
-
- Template files required for admin:
-
template/layout-admin.phtml
- backoffice layout.
-
- Stylesheet files required:
-
asset/css/style.css
- main css file; -
asset/css/form.css
- generic form css file.
-
config.php
As we mentioned above, this file defines basic information of the theme, codes in the file are:
return array(
'version' => '1.0.0',
'title' => 'Pi Theme',
'author' => 'Pi Development Team',
'screenshot' => 'image/screenshot.png',
'license' => 'Creative Common License http://creativecommons.org/licenses/by/3.0/',
'active' => true,
'type' => 'both', // Potential value: 'both', 'admin', 'front', default as 'both'
'description' => 'Default theme for Pi',
);
-
screenshot
- theme thumbnail for user to view; -
type
- defines the type of layouts available in the theme, its potential value can beboth
,admin
andfront
, if the field is not set,both
value will be used as default.
module package
As we know, packages in module folder is used to define theme for modules, therefore, template files in template folder has the same name as that of module templates. These packages should have a structure such as:
module
{module theme name}
asset
js
image
css
template
{template files}
In the template folder, some template files are needed for displaying pages for this application. These files define themes of front-end, admin-end and error pages.
layout-front.phtml
This template is used to display the homepage of front-end, it's a complete html page which includes doctype
, head
and body
. View helpers that we will introduce later can be used to load HTML tags <head>
, <meta>
and <script>
.
The body of the page is divided into several parts, they are used to display blocks and module. Here we use a table to simple show the body layout of page:
+--------------------+---------------+---------------+---------------+--------------------+
| | | | | |
| | Zone 2 | Zone 3 | Zone 4 | |
| | | | | |
| +---------------+---------------+---------------+ |
| | | |
| Zone 1 | Module | Zone 8 |
| | | |
| +---------------+---------------+---------------+ |
| | | | | |
| | Zone 5 | Zone 6 | Zone 7 | |
| | | | | |
+--------------------+---------------+---------------+---------------+--------------------+
This layout can be simply described by the following codes:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $locale ?>" lang="<?php echo $locale ?>">
<head>
<?php echo $this->headTitle() ?>
<?php echo $this->headMeta() ?>
<?php echo $this->headLink() ?>
<?php echo $this->headScript() ?>
</head>
<body>
<!-- Header: logo here -->
<div>...</div>
<!-- Global navigation -->
<?php // use navigation() helper to output navigation ?>
<!-- Load blocks -->
<?php $blocks = $this->blocks()?>
<table cellspacing="0">
<tr>
<!-- Left blocks loop -->
<?php if (isset($blocks['1'])) {?>
<td id="Pi-zone-1">
<?php // display blocks ?>
</td>
<?php }?>
<td id="Pi-zone-center">
<!-- Display center blocks if any -->
<table cellspacing="0">
<!-- Display center-center blocks if any --> ...
<!-- Display center-left blocks if any --> ...
<!-- Display center-right blocks if any --> ...
</table>
<!-- Content module page -->
<?php if (!empty($content) && ($content != ' ')) {?><div id="Pi-content"><?php echo $content?></div><?php }?>
<!-- Start center bottom blocks loop --> ...
</td>
<!-- Right blocks loop --> ...
</tr>
</table>
<!-- Footer -->
<div>...</div>
</body>
</html>
Pi provides us a navigation()
helper for displaying navigation, all navigation data are stored in database when installs, so this only users need to do is call this helper, and it will output navigation automatically.
<?php $navigation = $this->navigation('front', true);?>
<?php if ($navigation) { ?>
<div class="Pi-topbar">
<div id="Pi-top-menu"><?php echo $navigation->menu()->setUlClass('jd_menu');?></div>
<div id="Pi-top-navigation"><?php echo $navigation->breadcrumbs()?></div>
</div>
<?php } ?>
This code will output a navigation with css if you have set class jd_menu
.
The contents of blocks are acquired by calling helper blocks()
, then the block.phtml
template will be included to display blocks. The template block.phtml
will be introduced later.
For example:
<?php $blocks = $this->blocks()?>
<table cellspacing="0">
<tr>
<?php if (isset($blocks['1'])) {?>
<td id="Pi-zone-1">
<?php foreach ($blocks['1'] as $key => $block) {?>
<?php include $this->template('block.phtml');?>
<?php }?>
</td>
...
</tr>
</table>
In the code, the blocks()
method helps to load all the blocks' information of this page for later displaying if they are set.
NOTE: it is strongly recommended to use Pi-
as prefix for all id's used in theme to avoid conflicts.
layout-admin.phtml
The layout-admin.phtml
is used to display homepage of admin-end. This template is also a complete page which is as same as layout-front.phtml
. But this page does not be divided into blocks and module.
NOTE: remember to set the parameter of navigation
to admin
.
<?php $navigation = $this->navigation('admin', true);
block.phtml
The block.phtml
template is used to display the content of blocks. It is included in the layout-front.phtml
file by the php method include
. The codes of this file may be:
<div id="Pi-block-<?php echo $block['name'] ?: $block['id']; ?>" class="block-container<?php if (!empty($block['class'])) { echo ' ' . $block['class']; }?>">
<fieldset>
<?php
if (!empty($block['title'])) {
if (!empty($block['link'])) {
$title = sprintf('<a href="%s" title="%s">%s</a>', $block['link'], $block['title'], $block['title']);
} else {
$title = $block['title'];
}
printf('<legend class="block-title">%s</legend>', $title);
}
?>
<div class="block-content"><?php echo $block['content']?></div>
</fieldset>
</div>
The variable $block
here is defined in the layout-front.phtml
file.
page-zone.phtml
This template is used for block manipulation on a page.
In the default theme package, Pi provides us several templates for displaying simple pages, they are:
layout-content.phtml
This template simply displays content.
<?php echo $content ?>
layout-simple.phtml
This template displays main content as well as HTML <head>
element and page header.
layout-style.phtml
This template displays main content as well as HTML <head>
element.
The following templates are used when errors occur.
error-404.phtml
This template is used to list the errors when a 404 error occurs.
error-index.phtml
This template is used to list errors and exceptions when they occur.
denied.phtml
This template displays a deny message when user have no permission to request the page.
You might found that you have troublesomely wrote scripts in your view page over and over when code without framework, fortunately, Pi provides us with plenty of view helpers to complete your work quickly and conveniently.
A helper is simply a class that implements the interface Zend\View\Helper
. Helpers of Pi inherit from that of Zend Framework 2. Helper simply defines two methods, setView()
, which accepts a Zend\View\Renderer
instance/implementation, and getView()
, used to retrieve that instance. Zend\View\PhpRenderer
composes a plugin broker, allowing you to retrieve helpers, and also provides some method overloading capabilities that allow proxying method calls to helpers.
For example, if we create a class called js
in the Pi/View/Helper/js.php
or Zend/View/Helper/js.php
and add a __invoke()
method, then we can use the method in the phtml file.
$this->js();
asset
The asset folder of theme is used to store static file, such as js, css and images. This folder will be published to the www
folder of Pi, so the static files can be requested by users. The asset
helper helps for building an asset URI, then we can use this URI to request the file. for example, you can write the following codes in your phtml file:
$this->asset('theme/default', 'css/style.css');
This code will return a string such as http://localhost/Pi/www/asset/theme-default/css/style.css
if you set your Pi folder's name to Pi
.
The first parameter of this helper is a string describes the name of component. This string consists of two parts connected by characters exclude letters (a-z, A-Z), numeral (0-9) and dash (-), a slash (/) is recommended. The previous part of the string should be theme
or module
which contains asset folder and the later part is the name of theme or module.
The second parameter is the file name you want to build.
echo $this->asset('module/demo', 'js/demo.js');
Output:
'http://localhost/Pi/www/asset/module-demo/js/demo.js'
Other example:
<img src="<?php echo $this->asset('module/demo', 'image/logo.png'); ?>" />
assetLocale
This helper is used to build locale asset URI inside current theme. It takes three parameters: the first one indicates the file name, the second one indicates the locale file to choose, if it is not set, the system locale will be used, and the third one decides whether to append version for file path.
echo $this->assetLocale('style.css');
echo $this->assetLocale('js1.js', 'Zh-CN', false);
If the system locale is gray:'en'
, and current theme is 'default'
, the code above will output:
'http://localhost/pi/www/asset/theme-default/locale/en/style.css?1355197213'
'http://localhost/pi/www/asset/theme-default/locale/Zh-CN/js1.js'
NOTE: users should check the Append version
checkbox in general configuration page to enable versioning.
assetModule
This helper is more conveniently to build a URI for module, because you can only assign the file name if you want to get a URI for current module. This helper takes two parameters, the first parameter should be assigned with a file name string, and the second parameter is a module name string, this parameter can be ignored if you build a URI for current module. If you want to build a URI of other module, you must assign the module name to the second parameter.
This helper will also return a string contain an asset URI of a module.
For example, supposing you add a phtml file in a module call demo
with following code:
echo $this->assetModule('js/demo.js');
It will output the following URI:
'http://localhost/Pi/www/asset/module-demo/js/demo.js'
Now if you want to build a URI of other module, such as article
, you should assign the second parameter such as:
echo $this->assetModule('css/style.css', 'article');
The output is:
'http://localhost/Pi/www/asset/module-article/css/style.css'
assetTheme
This helper builds URI for asset folder of theme only. The usage of this function is as same as assetModule
, the two parameters are file name and module name, respectively. The second parameter can be ignored if you build a URI of current theme.
For example, the current theme named default
:
echo $this->assetTheme('image/logo.png');
echo $this->assetTheme('js/jquery.js', 'dev');
These codes will output:
'http://localhost/Pi/www/asset/theme-default/image/logo.png'
'http://localhost/Pi/www/asset/theme-dev/js/jquery.js'
backbone
This helper is used to load javascript files of backbone. The helper will autoload backbone.min.js
and underscore-min.js
files, and other static files can also be load if their file name is passed.
$this->backbone();
$this->backbone('js1.js');
$this->backbone(array(
'backbone.min.js', 'style.css'
));
basePath
This helper is used to get the base path of application.
echo $this->basePath();
echo $this->basePath('asset/image/logo.png');
Output:
'http://localhost/Pi/www/'
'http://localhost/Pi/www/asset/image/logo.png'
blocks
Pi divides a page into a module part and several blocks parts. A block is an independent application relates to current module. Pi encapsulates a helper named blocks**for users to load blocks of specified zones. The
blocks()` helper will return an array contains blocks information according to passed parameter.
The blocks
helper takes only one parameter that indicates the zone. The value of parameter should be 0 to 8. Blocks of different zones will be loaded according to its first parameter, if the passed parameter is set to null, blocks of all zones will be loaded.
$blocks = $this->blocks();
$blocks = $this->blocks('5');
foreach ($blocks['5'] as $key => $block) {
...
}
The code above is used in the .phtml
template, if you want to call this helper in general PHP file, you should use the following codes:
$blocksHelper = $this->plugin('blocks')->setEvent($mvcEvent);
$leftBlocks = $blocksHelper('0');
$rightBlcoks = $blocksHelper->load('8');
bootstrap
Pi allows users to use bootstrap
to achieve div+css, users only need to include the bootstrap file name and then insert the class name into their HTML tags, the whole front style will come true automatically.
This helper takes two parameters, the first one decides the static files to load, and the second parameter decide whether to load bootstrap.min.css
, and the default value is true.
$this->bootstrap();
$this->bootstrap('css/bootstrap.responsive.min.css');
$this->bootstrap(array(
'css/bootstrap.responsive.css',
'js/bootstrap.js',
));
css
The HTML <link>
element is used for linking varieties of resources for your page, such as stylesheets, feeds, favicons, trackbacks and more. The css
is a helper of Pi library, which inherit from Zend helper, and call headLink
helper of Zend to create and aggregate those elements mentioned above for later retrieval and output in your layout script.
There is only one parameter of css
helper, and it can be string or array which contains file path of resources. This helper will store path information in an AbstractHelper
object, and you should add extra codes to output them.
In Pi, js, css resources are stored in static folder, therefore, you may fetch the URI first:
$pathToCss = Pi::url('static') . '/css';
$this->css($pathToCss . '/style.css');
$this->css(array(
$pathToCss . '/css1.css',
$pathToCss . '/css2.css',
));
echo $this->headLink();
Then if you click right button to view page source, you will find a HTML <link>
element has been added:
'<link href="http://localhost/Pi/www/static/css/style.css" media="screen" rel="stylesheet" type="text/css" >'
'<link href="http://localhost/Pi/www/static/css/css1.css" media="screen" rel="stylesheet" type="text/css" >'
'<link href="http://localhost/Pi/www/static/css/css2.css" media="screen" rel="stylesheet" type="text/css" >'
NOTE: you must add echo $this->headLink();
at the end of your code if you want to output a HTML <link>
element.
escape
It is strongly recommended to add escape for output variables, the escape
helper helps user to escape easily.
echo $this->escape($value);
footScript
ga
This helper is used to add GA code for users to get statistical data of their site. It takes only one parameter which is the GA account. And the default account from configuration will be used if it is not set.
$this->ga();
$this->ga('UA-XXXXX-X');
js
The js
helper is a Pi helper which inherit from AbstractHelper
, this helper allows you to manage a HTML <script>
element for later output, the HTML <script>
element is used to either provide inline client-side scripting elements or link to
a remote resource containing client-side scripting code.
The js
helper has only one parameter, it can be string or array describes the name of js files. This helper do not output HTML <script>
element directly, you should add echo $this->headScript();
to output it.
The JavaScript files are also stored in the static
folder in Pi. You should fetch a static URI first.
$pathToJs = Pi::url('static') . '/js';
$this->js($pathToJs . '/js1.js');
$this->js(array(
$pathToJs . '/js2.js',
$pathToJs . '/js3.js',
));
echo $this->headScript();
These codes will output:
'<script type="text/javascript" src="http://localhost/Pi/www/static/js/js1.js"></script>'
'<script type="text/javascript" src="http://localhost/Pi/www/static/js/js2.js"></script>'
'<script type="text/javascript" src="http://localhost/Pi/www/static/js/js3.js"></script>'
jQuery
The jQuery
is a JavaScript framework, it helps users to deal with HTML documents, events and animation conveniently, it also provides with AJAX
. The jQuery
helper inherits from AbstractHelper
of Zend, it loads js or css files for later output.
The jQuery
helper contains only one parameter which can be a string or an array consists of string elements. Strings are name of css or js files, if you do not set its parameter, a js file named jquery.min.js
will be loaded.
NOTE: you should add echo $this->headScript();
or echo $this->headLink();
to output your HTML tags.
$this->jQuery();
$this->jQuery('extension.js');
$this->jQuery(array(
'js1.js',
'css1.css',
));
echo $this->headScript();
echo $this->headLink();
The outputs are:
'<script type="text/javascript" src="http://localhost/Pi/www/static/js/jquery/jquery.min.js"></script>'
'<script type="text/javascript" src="http://localhost/Pi/www/static/js/jquery/extension.js"></script>'
'<script type="text/javascript" src="http://localhost/Pi/www/static/js/jquery/js1.js">'
'<link href="http://localhost/Pi/www/static/js/jquery/css1.css" rel="stylesheet" type="text/css" >'
meta
The HTML <meta>
element is used to provide meta information about your HTML document, such as keywords, document character set, caching pragmas, etc. Meta tags may be either of the http-equiv
or name
types, must contain a content
attribute, and also have either of the lang
or scheme
modifier attributes.
The meta
helper will select the meta
category of application's config
table, and then return the result according to given parameter. This helper has only one parameter typed string, it is the name of meta element. The value of the parameter can be copyright
, description
, keywords
or author
here.
echo $this->meta('keywords');
echo $this->meta()->getMeta('keywords');
Output:
'Pi, Web application'
'Pi, Web application'
If you do not set the parameter, an AbstractHelper
containing nothing will be returned, then you can call its method to achieve other function.
// Fetching data of general category from 'config' table
echo $this->meta()->getConfig('sitename');
// Assign meta data to root view model and initialize views
$this->meta()->assign();
The first line will output:
'Web Applications'
template
In Pi, HTML tags are coded in a special file which has an extension named .phtml
. The template
helper is used to decide which template file to use in current theme. This helper takes only one parameter which is a string containing module and template name data. The full string has a format such as {module name}:{template name}.phtml
. If you do not set module name, current module will be used. The templates in theme package have the highest priority.
For example, if you install your Pi in D disc, and current module is system
:
echo $this->template('block.phtml');
echo $this->template('module/system:block/login.phtml');
Output:
'D:/wamp/www/Pi/usr/theme/default/template/block.phtml'
'D:/wamp/www/Pi/usr/module/system/template/block/login.phtml'
Using following codes to add a template:
include $this->template('block.phtml');
url
Pi adopts a Module-Controller-Action model, you should set module name, controller name and action name in url to route to right page. The url
helper provides the function to generate a URL by given parameters.
The url helper takes four parameters, the first is route name, it allow you to choose your route type, Pi provides four types for user to choose, which are default
, admin
, home
and feed
, it will set to default
if you give a null value; the second parameter is an array which contain module name, controller name and action name, if you do not give the module name, current module will be used; the third parameter is an option parameter for route and the fourth parameter is a Boolean which decided whether to reuse matched parameters.
$this->url('', array(
'module' => 'system',
'controller' => 'index',
'action' => 'index',
));
$this->url('home');
$this->url('default', array(
'controller' => 'index',
'action' => 'index',
));
You can also add your parameters to the second parameter of url
helper. These parameters will post by GET method, for example:
$this->url('' array(
'controller' => 'login',
'action' => 'login',
'param' => 'hello',
));
The url will be:
'path/to/www/login/login/param-hello'
Then you can use params()
method to fetch the value in action method:
$this->params('param');
widget
In Pi, blocks are used to implement a special function in page, you can add or remove a block from you page by coding your pthml file of theme package. The widget
helper will allow user to fetch and render a block.
The widget
helper inherits from the block
helper, it takes two parameters, the first can be a block name string, or a number describes a block. The second parameter is an array.
$this->widget('block-name', array('title_hidden' => 1, 'opt1' => 'val1', 'opt2' => 'val2'));
$this->widget('block-name', array('link' => '/link/to/a/URL', 'opt1' => 'val1', 'opt2' => 'val2'));
$this->widget('block-name', array('style' => 'specified-css-class', 'opt1' => 'val1', 'opt2' => 'val2'));
$this->widget(24, array('opt1' => 'val1', 'opt2' => 'val2'));
$this->widget()->load(24);
$this->widget()->render($blockModel);
These codes will load and display blocks in the indicated position.
navigation
The navigation
helper is used to load a navigation for current module of Pi application.
This helper takes two parameters, the first one is name of navigation to load, it can also be comprehended as section
in general. In Pi, it can be set to front
or admin
to load a front navigation or admin navigation, or name indicate custom navigation definded by users. A front navigation will be used if this parameter is not set. The second parameter is an array and its fields will be used to configure cache.
NOTE: the data used to generate navigation are fetched from core_navigation_node
table, these data are first defind in the config/navigation.php
file.
// load a front navigation
$this->navigation('front');
// load a admin navigation and set cache ttl, level and key
$this->navigation('admin', array(
'cache_ttl' => 86400,
'cache_level' => none,
'cache_id' => 'nav_system'));
// render a custom navigation 'cms' if current module is demo
$this->navigation('demo-cms')->render();
Menu
This class is used to operate menu and can be call by $this->navigation()->menu()
.
this setUIClass(string $ulClass);
this setOnlyActiveBranch(bool $flag = true);
this escapeLabels(bool $flag = true);
this setRenderParent(bool $flag = true);
this setPartial(string|array $partial);
string renderMenu(AbstractContainer $container = null, array $options = array());
array renderPair(AbstractContainer $container = null, array $options = array());
string render($AbstractContainer $container = null);
- setUIClass()
Set css class to use for the first 'ul' element when rendering.
$this->navigation('front')->menu()->setUIClass('jd_menu');
- setOnlyActiveBranch()
This method decides whether to render active branch only, the application will only render active branch if set to true.
$this->navigation('front')->menu()->setOnlyActiveBranch();
- escapeLabels()
Indicating whether to escape labels. Its default value is true.
$this->navigation('front')->menu()->escapeLabels();
-
setRenderParents()
$this->navigation('front')->menu()->setRenderParents();
-
setPartial()
-
render()
Rendering menu.
$this->navigation('front')->menu()->render();
Breadcrumbs
This class is used to operate breadcrumbs and can be call by $this->navigation()->breadcrumbs()
.
this setSeparator(string $sepatator);
this setLinkLast(bool $linkLast);
string render(AbstractContainer $container = null);
- setSepatator()
Set breadcrumb separator.
$this->navigation('front')->breadcrumbs()->setSeparator('<span class="divider">></span>');
- setLinkLast()
Deciding whether last page in breadcrumbs should be hyperlinked.
$this->navigation('front')->breadcrumbs()->setLinkLast(true);
- render()
Rendering breadcrumb.
$this->navigation('front')->breadcrumbs()->render();
nav
This class is used to load a global navigation, it will read navigation name from core_config
table, and then render the navigation by calling navigation
helper. Therefore by using this helper in template, users can install custom navigation in admin section and then the custom navigation will be displayed.
The value passed to this method can only be front
and admin
to indicate load front global navigation or adminstration global navigation, respectively.
Its second parameter is an optional array for setting cache.
$this->nav('front');
$this->nav('admin', array(
'cache_ttl' => 84600,
'cache_id' => 'system_nav',
));
Please refer to http://packages.zendframework.com/docs/latest/manual/en/modules/zend.view.helpers.html for more helps of navigation.
Predefine variables are variables define by system, users can output they value in phtml file directly without define them. These variables are declared in usr/module/system/config/config.php
with they default value.
sitename
The variable sitename
is the name of site, and its default value is Web Applications
.
Using in template files:
<?php echo $sitename; ?>
Output:
'Web Applications'
slogan
This variable describes the slogan of site, and its set to Powered by Pi.
by default.
adminmail
This variable describes administration email address for conveniently contact, it has no default value.
locale
This variable decides which language package to use, its default value set to the locale you choose when you install the Pi.
charset
This variable is charset for page to display.
timezone_server
This variable describes timezone set by server, it has no default value.
timezone_system
This variable is the timezone for application system, it also has no default value.
theme, theme_admin
These two variables describe the theme for front end and admin area, respectively, they have the same default value which is default
.
NOTE: parts of definition are refer to Zend Framework 2 manual.