Moodle開發筆記4-Theme開發
通過 Theme,你可以修改整個 moodle site的外觀和風格。
一個 Theme最起碼包含下列東東:
l config.php 它設定了 theme要用到的 css file,以及其他 style option
l styles.php 它是 standard的,不用動它。
l header.html 它是所有 moodle page的開頭部分。它實際是一個 php file
l footer.html 它是所有 moodle page的結尾部分。它實際是一個 php file
l theme用到的 css files。 你不需要完全重寫所有的 theme css,你可以使用 standard theme css,然後在其基礎上只重寫你需要修改的部分。
Theme主要是通過 CSS file來影響外觀,但這裡並不講解 css,而是 focus on programmer感興趣、的 header.html and footer.html,這 2個 file同樣也是 theme重要部分。
下面的例子是
1. 通過對 header.html 的修改來改變導航 link path。
2.
通過對
通過對 header.html 的修改來改變 navigation breadcrumbs (導航 link path ) .
具體要求是在 navigation breadcrumbs 中的 course link 之前新增該 course 的 category link 。例如原來的 navigation link path 是 ”Moodle Home > Course 01”, 那麼修改之後要在 Course 01 之前新增 category link
我們先來看看 moodle standard theme的 header.html
<html<?php echo $direction ?>>
<head>
<?php echo $meta ?>
<meta name="keywords" content="moodle, <?php echo $title ?> " />
<title><?php echo $title ?></title>
<link rel="shortcut icon"
href="<?php echo $CFG->themewww .'/'. current_theme() ?>/favicon.ico" />
<?php include("$CFG->javascript"); ?>
</head>
<body<?php
echo " $bodytags";
if ($focus) {
echo " onload=/"setfocus()/"";
}
?>>
<div id="page">
<?php
//Accessibility: 'headermain' is now H1, see theme/standard/styles_layout.css: .headermain
if ($home) { // This is what gets printed on the home page only,下列輸入只 for home page
?>
<?php print_container_start(true, '', ' header-home '); ?>
<h1 class="headermain"><?php echo $heading ?></h1>
<div class="headermenu"><?php echo $menu ?></div>
<?php print_container_end(); ?>
<?php } else if ($heading) {
// This is what gets printed on any other page with a heading
?>
<?php print_container_start(true, '', 'header' ); ?>
<h1 class="headermain"><?php echo $heading ?></h1>
<div class="headermenu"><?php echo $menu ?></div>
<?php print_container_end(); ?>
<?php } ?>
<?php
//Accessibility: breadcrumb trail/navbar now a DIV, not a table.
if ( $navigation ) { // This is the navigation bar with breadcrumbs
?>
<div class="navbar clearfix">
<!-- standard breadcrumb navigation on a page -->
<div class="breadcrumb"> <?php print_navigation($navigation); ?> </div>
<div class="navbutton"><?php echo $button; ?></div>
</div>
<?php } else if ($heading) { // If no navigation, but a heading, then print a line
?>
<hr />
<?php } ?>
<!-- END OF HEADER -->
<?php print_container_start(false, '', 'content' ); ?>
其中:
l 變數 $direction, $home, $meta, $navigation 等已經在之前的某個地方被定義好了
l print_container_start and print_container_en d函式。這 2個函式用於 structure a page in a known way so that it is easier to change the look of the page by using CSS 。 每一個 print_container_start會對應一個 print_container_end。 print_container_start的第三個引數是一個 id來判斷當前的 container是用什麼 css style來 structure 。例如上面的 header.html使用了 3次 print_container_start, id分別是 header_home, header, content。其中 最後一個 print_container_start並沒有使用 print_container_end,因為 print_container_end寫在 footer.html
l print_navigation 函式是用來 create standard breadcrumb navigation on a page
1. 假設我們自定義的 theme name 為“ customnav”,首先把 moodle_home/theme目錄下建立目錄“ customnav”,然後把 moodle_home/theme/standardlogo 目錄下的所有 files都賦值到“ customnav”下。這樣實際上你已經建立了一個 theme,它和 standardlogo theme一摸一樣,只不過 theme name不同。
2. 要改變 navigation breadcrumbs ,我們只需要修改 header.html。根據上面的 header.html程式碼,我們要在 call print_navigation 函式之前修改變數 $ navigation ,使其包含 category info 即可 。
$ navigation 變數是一個 key-value array,它有 2個 key:
l newnav 其值總是 ’ 1 ’ ,表示 using the 'new' navigation API 。當前例子不需要理會它
l navlinks 其值是一個 string,它才是真正包含要輸出的 navigation info的東東 ,我們要改動的就是該變數的值。
先分析 $navigation['navlinks'] 的值的格式:
它的每一個 navigation node都會用 <li> </li>包住。如果 navigation node的數目小於 2個,那麼表明並沒有進入到 course node裡,不需要新增 category node,這是因為 course node一定是放在 $navigation['navlinks'] 裡的第二個元素。
下面程式碼的邏輯是:
1) 先把 $navigation['navlinks'] explode to an array
2) 檢視 array element count 是否大於等於 2
3) 如果是,則獲取第 2 個 element,並從中提取 course short name(即去掉前後的 <li>/</li>/<a>/</a>)
4) 然後根據提取的 course short name 來從資料庫中獲取該 course屬於的 category。
5) 然後重新把組裝 $navigation['navlinks'] ,即把 category link和之前 explode出來的 array組裝到該變數。
6) 最後就可以執行 print_navigation 函數了。
/// If there are navigation pieces, separate them out.
if (!empty($navigation['navlinks'])) {
$pieces = explode ('<li>', $navigation['navlinks']);
} else {
$pieces = array();
}
/// If its possible there is a course piece, find course short name.
$sname = '';
if (count($pieces) > 1) {
$sname = $pieces[1];
// 檢視它是不是(通過檢視是否包含字串 ” /course/view.php ” )有則表示有 <a>
if (strpos($sname, '/course/view.php') !== false) {
$sname = substr($sname, 0, strpos($sname, '</a></li>'));
} else {
$sname = substr($sname, 0, strpos($sname, '</li>'));
}
$sname = trim(substr($sname, strrpos ($sname, '>')+1));
}
///find the category by course short name
if ($sname != '') {
$select = 'SELECT c.id, cc.id as catid, cc.name ';
$from = 'FROM '.$CFG->prefix.'course c ';
$join = 'INNER JOIN '.$CFG->prefix.'course_categories cc ON cc.id = c.category ';
$where = 'WHERE c.shortname = /''.$sname.'/'';
$sql = $select.$from.$join.$where;
$catinfo = get_record_sql($sql);
}
/// If we have category information, place it in the nav.
if (!empty($catinfo)) {
$catlink = $CFG->wwwroot.'/course/category.php?id='.$catinfo->catid;
$catpiece = '<li>';
// get_separator function returns a character as separator of the breadcrumb pieces
$catpiece .= get_separator();
// $CFG->framename is a configuration item that contains the name of any defined
//HTML frame that the site may sit in (typically none).
$catpiece .= '<a onclick="this.target=/''.$CFG->framename.'/'"
href="'.$catlink.'">'.$catinfo->name.'</a>';
$catpiece .= '</li>';
$navigation['navlinks'] = $pieces[0];
foreach ($pieces as $i => $piece) {
if ($i == 0) {
continue;
} else if ($i == 1) { //插入到第一個 element之前
$navigation['navlinks'] .= $catpiece;
}
$navigation['navlinks'] .= '<li>'.$piece;
}
}
通過對 footer.html 的修改來在 page footer 新增 a link
在 footer.html的
print_container_start(false, '', 'footer');
後面新增下列程式碼
$termsn = '/'. SITEID .'/termsofuse.html';
$footertext = '';
require_once($CFG->libdir.'/filelib.php');
/// Look for terms of use page
if (file_exists($CFG->dataroot.$termsn) ) {
$link = get_file_url($termsn, null, 'httpscoursefile') ;
/// To use with pop-up... Must be a relative URL.
$plink = str_replace($CFG->wwwroot, '', $link);
} else {
$link = false;
}
if ($link) {
$footertext .= '<a href="'.$link .'" target="_blank">Terms of Use</a>';
} else {
$footertext .= 'Terms of Use';
}
echo '<div class="footerlinks">'.$footertext.'</div><br />';
特別要注意的是:
1) $termsn = '/'. SITEID .'/termsofuse.html';
And file_exists($CFG->dataroot.$termsn)
SITEID 的值總是“ 1 ” (but it is safer to use the constant defined for this ),那麼“ $CFG->dataroot /1/xxx ”則是指向 the site directory of the Moodle data area 下的東東。
2) get_file_url($termsn, null, 'httpscoursefile')
注意: get_file_url 函式的第一個引數不需要加 $CFG->dataroot,這和 file_exists不同
但這時上面的 link還不能用,因為
$CFG->dataroot .'/'. SITEID .'/termsofuse.html'
目前並不存在。你需要 upload a termsofuse.html到 moodle site:
1. login as admin role
2. access “Site Administration > Front Page > Site Files”, click “upload a file”