- Added a template driven theme.

4.2.x
Dries Buytaert 2003-01-20 21:00:31 +00:00
parent 7e80b04c2c
commit 8b6d92fc69
5 changed files with 854 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,127 @@
body {
margin: 0px;
padding: 0px;
color: #000000;
background-color: #fff;
font-family: verdana, arial, helvetica, sans-serif;
}
body, td, tr {
font-size: 90%;
}
a {
text-decoration: none;
font-weight: normal;
}
a:link {
color: #378CE0;
}
a:visited {
color: #036;
}
a:hover {
text-decoration: underline;
}
p {
margin: 0 0 1em 0;
padding: 0;
}
img {
border-width: 0;
}
table #menu {
background-color: #69c;
padding: 5px 5px 0px 5px;
}
#menu logo {
vertical-align: bottom;
float: left;
}
#menu #links {
text-align: right;
float: right;
color: #9cf;
}
#menu #links #primary {
font-size: 1.1em;
}
#menu #links #primary a {
color: #fff;
font-weight: bold;
}
#menu #links #secundary {
font-size: 0.7em;
}
#menu #links #secundary a {
color: #9cf;
font-weight: bold;
}
#message {
background-color: #369;
padding: 10px 10px 10px 10px;
color: #fff;
}
#main {
margin: 10px 10px 10px 10px;
padding: 15px 15px 0px 15px;
}
#sidebar {
background-color: #ddd;
}
table #node {
padding-bottom: 25px;
}
table #block {
padding: 15px 15px 15px 15px;
margin: 5px 0px 5px 0px;
}
table #comment {
border: 1px solid #bbb;
padding: 15px 15px 15px 15px;
margin: 5px 0px 5px 0px;
}
#node #title, #block #title, #node #title a {
padding-bottom: 5px;
font-weight: bold;
font-size: 1.2em;
color: #888;
}
#node #author, #comment #author {
color: #999;
font-size: 0.8em;
padding-bottom: 10px;
}
#node #taxonomy {
color: #999;
font-size: 0.8em;
padding: 15px;
}
#node #taxonomy a {
color: #369;
}
#node #content, #comment #content {
padding-top: 5px;
}
#node #links, #comment #links {
padding-top: 10px;
color: #999;
}
#node #links a, #comment #links a {
font-weight: bold;
color: #369;
}
#comment #title {
font-weight: bold;
font-size: 1.1em;
color: #888;
}
#comment #new {
text-align: right;
font-weight: bold;
font-size: 0.7em;
float: right;
color: red;
}
#block #content {
font-size: 0.9em/1.1em;
}

View File

@ -0,0 +1,517 @@
<?
class XTemplate {
/*
xtemplate class 0.3pre
html generation with templates - fast & easy
copyright (c) 2000-2001 Barnabás Debreceni [cranx@users.sourceforge.net]
contributors:
Ivar Smolin <okul@linux.ee> (14-march-2001)
- made some code optimizations
Bert Jandehoop <bert.jandehoop@users.info.wau.nl> (26-june-2001)
- new feature to substitute template files by other templates
- new method array_loop()
!!! {FILE {VAR}} file variable interpolation may still be buggy !!!
latest stable & CVS versions always available @
http://sourceforge.net/projects/xtpl/
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 2.1 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details at
http://www.gnu.org/copyleft/lgpl.html
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
$Id$
*/
/***[ variables ]***********************************************************/
var $filecontents=""; /* raw contents of template file */
var $blocks=array(); /* unparsed blocks */
var $parsed_blocks=array(); /* parsed blocks */
var $preparsed_blocks=array(); /* preparsed blocks, for file includes */
var $block_parse_order=array(); /* block parsing order for recursive parsing (sometimes reverse:) */
var $sub_blocks=array(); /* store sub-block names for fast resetting */
var $VARS=array(); /* variables array */
var $FILEVARS=array(); /* file variables array */
var $filevar_parent=array(); /* filevars' parent block */
var $filecache=array(); /* file caching */
var $tpldir=""; /* location of template files */
var $FILES=null; /* file names lookup table */
var $file_delim="/\{FILE\s*\"([^\"]+)\"\s*\}/m"; /* regexp for file includes */
var $filevar_delim="/\{FILE\s*\{([A-Za-z0-9\._]+?)\}\s*\}/m"; /* regexp for file includes */
var $filevar_delim_nl="/^\s*\{FILE\s*\{([A-Za-z0-9\._]+?)\}\s*\}\s*\n/m"; /* regexp for file includes w/ newlines */
var $block_start_delim="<!-- "; /* block start delimiter */
var $block_end_delim="-->"; /* block end delimiter */
var $block_start_word="BEGIN:"; /* block start word */
var $block_end_word="END:"; /* block end word */
/* this makes the delimiters look like: <!-- BEGIN: block_name --> if you use my syntax. */
var $NULL_STRING=array(""=>""); /* null string for unassigned vars */
var $NULL_BLOCK=array(""=>""); /* null string for unassigned blocks */
var $mainblock="main";
var $ERROR="";
var $AUTORESET=1; /* auto-reset sub blocks */
/***[ constructor ]*********************************************************/
function XTemplate ($file,$tpldir="",$files=null,$mainblock="main") {
$this->tpldir = $tpldir;
if (gettype($files)=="array")
$this->FILES = $files;
$this->mainblock=$mainblock;
$this->filecontents=$this->r_getfile($file); /* read in template file */
$this->blocks=$this->maketree($this->filecontents,""); /* preprocess some stuff */
$this->filevar_parent=$this->store_filevar_parents($this->blocks);
$this->scan_globals();
}
/***************************************************************************/
/***[ public stuff ]********************************************************/
/***************************************************************************/
/***[ assign ]**************************************************************/
/*
assign a variable
*/
function assign ($name,$val="") {
if (gettype($name)=="array")
foreach ($name as $k=>$v)
$this->VARS[$k]=$v;
else
$this->VARS[$name]=$val;
}
/***[ assign_file ]*********************************************************/
/*
assign a file variable
*/
function assign_file ($name,$val="") {
if (gettype($name)=="array")
foreach ($name as $k=>$v)
$this->assign_file_($k,$v);
else
$this->assign_file_($name,$val);
}
function assign_file_ ($name,$val) {
if (isset($this->filevar_parent[$name])) {
if ($val!="") {
$val=$this->r_getfile($val);
foreach($this->filevar_parent[$name] as $parent) {
if (isset($this->preparsed_blocks[$parent]) and !isset($this->FILEVARS[$name]))
$copy=$this->preparsed_blocks[$parent];
else if (isset($this->blocks[$parent]))
$copy=$this->blocks[$parent];
preg_match_all($this->filevar_delim,$copy,$res,PREG_SET_ORDER);
foreach ($res as $v) {
$copy=preg_replace("/".preg_quote($v[0])."/","$val",$copy);
$this->preparsed_blocks=array_merge($this->preparsed_blocks,$this->maketree($copy,$parent));
$this->filevar_parent=array_merge($this->filevar_parent,$this->store_filevar_parents($this->preparsed_blocks));
}
}
}
}
$this->FILEVARS[$name]=$val;
}
/***[ parse ]***************************************************************/
/*
parse a block
*/
function parse ($bname) {
if (isset($this->preparsed_blocks[$bname])) {
$copy=$this->preparsed_blocks[$bname];
}
else if (isset($this->blocks[$bname]))
$copy=$this->blocks[$bname];
else
$this->set_error ("parse: blockname [$bname] does not exist");
/* from there we should have no more {FILE } directives */
$copy=preg_replace($this->filevar_delim_nl,"",$copy);
/* find & replace variables+blocks */
preg_match_all("/\{([A-Za-z0-9\._]+?)}/",$copy,$var_array);
$var_array=$var_array[1];
foreach ($var_array as $k=>$v) {
$sub=explode(".",$v);
if ($sub[0]=="_BLOCK_") {
unset($sub[0]);
$bname2=implode(".",$sub);
$var=$this->parsed_blocks[$bname2];
$nul=(!isset($this->NULL_BLOCK[$bname2])) ? $this->NULL_BLOCK[""] : $this->NULL_BLOCK[$bname2];
if ($var=="") {
if ($nul=="") {
$copy=preg_replace("/^\s*\{".$v."\}\s*\n*/m","",$copy);
} else {
$copy=preg_replace("/\{".$v."\}/","$nul",$copy);
}
} else {
$var=trim($var);
$copy=preg_replace("/\{".$v."\}/","$var",$copy);
}
} else {
$var=$this->VARS;
foreach ($sub as $v1)
$var=$var[$v1];
$nul=(!isset($this->NULL_STRING[$v])) ? ($this->NULL_STRING[""]) : ($this->NULL_STRING[$v]);
$var=(!isset($var))?$nul:$var;
if ($var=="")
$copy=preg_replace("/^\s*\{".$v."\}\s*\n/m","",$copy);
$copy=preg_replace("/\{".$v."\}/","$var",$copy);
}
}
$this->parsed_blocks[$bname].=$copy;
/* reset sub-blocks */
if ($this->AUTORESET && (!empty($this->sub_blocks[$bname]))) {
reset($this->sub_blocks[$bname]);
foreach ($this->sub_blocks[$bname] as $k=>$v)
$this->reset($v);
}
}
/***[ rparse ]**************************************************************/
/*
returns the parsed text for a block, including all sub-blocks.
*/
function rparse($bname) {
if (!empty($this->sub_blocks[$bname])) {
reset($this->sub_blocks[$bname]);
foreach ($this->sub_blocks[$bname] as $k=>$v)
if (!empty($v))
$this->rparse($v);
}
$this->parse($bname);
}
/***[ insert_loop ]*********************************************************/
/*
inserts a loop ( call assign & parse )
*/
function insert_loop($bname,$var,$value="") {
$this->assign($var,$value);
$this->parse($bname);
}
/***[ array_loop ]*********************************************************/
/*
parses a block for every set of data in the values array
*/
function array_loop($bname, $var, &$values)
{
if (gettype($values)=="array")
{
foreach($values as $v)
{
$this->assign($var, $v);
$this->parse($bname);
}
}
}
/***[ text ]****************************************************************/
/*
returns the parsed text for a block
*/
function text($bname) {
return $this->parsed_blocks[isset($bname) ? $bname :$this->mainblock];
}
/***[ out ]*****************************************************************/
/*
prints the parsed text
*/
function out ($bname) {
$length=strlen($this->text($bname));
header("Content-Length: ".$length);
echo $this->text($bname);
}
/***[ reset ]***************************************************************/
/*
resets the parsed text
*/
function reset ($bname) {
$this->parsed_blocks[$bname]="";
}
/***[ parsed ]**************************************************************/
/*
returns true if block was parsed, false if not
*/
function parsed ($bname) {
return (!empty($this->parsed_blocks[$bname]));
}
/***[ SetNullString ]*******************************************************/
/*
sets the string to replace in case the var was not assigned
*/
function SetNullString($str,$varname="") {
$this->NULL_STRING[$varname]=$str;
}
/***[ SetNullBlock ]********************************************************/
/*
sets the string to replace in case the block was not parsed
*/
function SetNullBlock($str,$bname="") {
$this->NULL_BLOCK[$bname]=$str;
}
/***[ set_autoreset ]*******************************************************/
/*
sets AUTORESET to 1. (default is 1)
if set to 1, parse() automatically resets the parsed blocks' sub blocks
(for multiple level blocks)
*/
function set_autoreset() {
$this->AUTORESET=1;
}
/***[ clear_autoreset ]*****************************************************/
/*
sets AUTORESET to 0. (default is 1)
if set to 1, parse() automatically resets the parsed blocks' sub blocks
(for multiple level blocks)
*/
function clear_autoreset() {
$this->AUTORESET=0;
}
/***[ scan_globals ]********************************************************/
/*
scans global variables
*/
function scan_globals() {
reset($GLOBALS);
foreach ($GLOBALS as $k=>$v)
$GLOB[$k]=$v;
$this->assign("PHP",$GLOB); /* access global variables as {PHP.HTTP_HOST} in your template! */
}
/******
WARNING
PUBLIC FUNCTIONS BELOW THIS LINE DIDN'T GET TESTED
******/
/***************************************************************************/
/***[ private stuff ]*******************************************************/
/***************************************************************************/
/***[ maketree ]************************************************************/
/*
generates the array containing to-be-parsed stuff:
$blocks["main"],$blocks["main.table"],$blocks["main.table.row"], etc.
also builds the reverse parse order.
*/
function maketree($con,$parentblock="") {
$blocks=array();
$con2=explode($this->block_start_delim,$con);
if (!empty($parentblock)) {
$block_names=explode(".",$parentblock);
$level=sizeof($block_names);
} else {
$block_names=array();
$level=0;
}
foreach ($con2 as $k=>$v) {
$patt="($this->block_start_word|$this->block_end_word)\s*(\w+)\s*$this->block_end_delim(.*)";
if (preg_match_all("/$patt/ims",$v,$res,PREG_SET_ORDER)) {
// $res[0][1] = BEGIN or END
// $res[0][2] = block name
// $res[0][3] = kinda content
if ($res[0][1]==$this->block_start_word) {
$parent_name=implode(".",$block_names);
$block_names[++$level]=$res[0][2]; /* add one level - array("main","table","row")*/
$cur_block_name=implode(".",$block_names); /* make block name (main.table.row) */
$this->block_parse_order[]=$cur_block_name; /* build block parsing order (reverse) */
$blocks[$cur_block_name].=$res[0][3]; /* add contents */
$blocks[$parent_name].="{_BLOCK_.$cur_block_name}"; /* add {_BLOCK_.blockname} string to parent block */
$this->sub_blocks[$parent_name][]=$cur_block_name; /* store sub block names for autoresetting and recursive parsing */
$this->sub_blocks[$cur_block_name][]=""; /* store sub block names for autoresetting */
} else if ($res[0][1]==$this->block_end_word) {
unset($block_names[$level--]);
$parent_name=implode(".",$block_names);
$blocks[$parent_name].=$res[0][3]; /* add rest of block to parent block */
}
} else { /* no block delimiters found */
if ($k)
$blocks[implode(".",$block_names)].=$this->block_start_delim;
$blocks[implode(".",$block_names)].=$v;
}
}
return $blocks;
}
/***[ store_filevar_parents ]***********************************************/
/*
store container block's name for file variables
*/
function store_filevar_parents($blocks){
$parents=array();
foreach ($blocks as $bname=>$con) {
preg_match_all($this->filevar_delim,$con,$res);
foreach ($res[1] as $k=>$v)
$parents[$v][]=$bname;
}
return $parents;
}
/***[ error stuff ]*********************************************************/
/*
sets and gets error
*/
function get_error() {
return ($this->ERROR=="")?0:$this->ERROR;
}
function set_error($str) {
$this->ERROR="<b>[XTemplate]</b>&nbsp;<i>".$str."</i>";
trigger_error($this->get_error());
}
/***[ getfile ]*************************************************************/
/*
returns the contents of a file
*/
function getfile($file) {
if (!isset($file)) {
$this->set_error("!isset file name!");
return "";
}
// check if filename is mapped to other filename
if (isset($this->FILES))
{
if (isset($this->FILES[$file]))
$file = $this->FILES[$file];
}
// prepend template dir
if (!empty($this->tpldir))
$file = $this->tpldir."/".$file;
if (isset($this->filecache[$file]))
$file_text=$this->filecache[$file];
else {
if (is_file($file)) {
if (!($fh=fopen($file,"r"))) {
$this->set_error("Cannot open file: $file");
return "";
}
$file_text=fread($fh,filesize($file));
fclose($fh);
} else {
$this->set_error("[$file] does not exist");
$file_text="<b>__XTemplate fatal error: file [$file] does not exist__</b>";
}
$this->filecache[$file]=$file_text;
}
return $file_text;
}
/***[ r_getfile ]***********************************************************/
/*
recursively gets the content of a file with {FILE "filename.tpl"} directives
*/
function r_getfile($file) {
$text=$this->getfile($file);
while (preg_match($this->file_delim,$text,$res)) {
$text2=$this->getfile($res[1]);
$text=preg_replace("'".preg_quote($res[0])."'",$text2,$text);
}
return $text;
}
} /* end of XTemplate class. */
/*
$Log$
Revision 1.1 2003/01/20 21:00:31 dries
- Added a template driven theme.
Revision 1.1 2002/12/10 23:11:59 ax
[argh - cvs @*#! didn't add any files with the last commit ... now, then (we should really give subversion a try: "Directories, renames, and file meta-data are versioned"]
- renamed from "ax" to "XTemplate_Tableless" to make people looking for ... this find it
- updated to CVS
- fixed some styles
- em/%'ized stylesheet (relative sizes) and "chaptered" into sections
- added 3 screenshots
Revision 1.2 2001/09/19 14:11:25 cranx
fixed a bug in the whitespace-stripping block variable interpolating regexp.
Revision 1.1 2001/07/11 10:42:39 cranx
added:
- filename substitution, no nested arrays for the moment, sorry
(including happens when assigning, so assign filevar in the outside blocks first!)
Revision 1.5 2001/07/11 10:39:08 cranx
added:
- we can now specify base dir
- array_loop()
- trigger_error in set_error
modified:
- newline bugs fixed (for XML)
- in out(): content-length header added
- whiles changed to foreach
- from now on, the class is php4 only :P
*/
?>

View File

@ -0,0 +1,140 @@
<?php
class Theme_xtemplate extends BaseTheme {
var $primary_links = "edit me";
var $secundary_links = "edit me";
var $message = "edit me";
function system($field) {
$system["name"] = "xtemplate";
return $system[$field];
}
function Theme_xtemplate() {
include_once("themes/xtemplate/xtemplate.inc");
$this->template = new XTemplate("themes/xtemplate/xtemplate.xtmpl");
$this->template->SetNullBlock(" "); // "" doesnt work!
}
function node($node, $main) {
$terms = array();
if (function_exists("taxonomy_node_get_terms")) {
foreach (taxonomy_node_get_terms($node->nid) as $term) {
$terms[] = l($term->name, array("or" => $term->tid), "index");
}
}
$this->template->assign(array (
"title" => ucfirst($node->title),
"taxonomy" => $this->links($terms),
"author" => format_name($node),
"date" => format_date($node->created),
"content" => ($main && $node->teaser) ?
check_output($node->teaser) :
check_output($node->body)));
if ($links = link_node($node, $main)) {
$this->template->assign("links", $this->links($links));
}
$this->template->parse("node");
print $this->template->text("node");
$this->template->reset("node");
}
function comment($comment, $link = 0) {
$this->template->assign(array (
"title" => ucfirst($comment->subject),
"author" => format_name($comment),
"date" => format_date($comment->timestamp),
"content" => check_output($comment->comment),
"links" => $link));
if ($comment->new) {
$this->template->parse("comment_new");
print $this->template->text("comment_new");
$this->template->reset("comment_new");
}
else {
$this->template->parse("comment_old");
print $this->template->text("comment_old");
$this->template->reset("comment_old");
}
}
function header() {
$this->template->assign(array(
"name" => variable_get("site_name", ""),
"slogan" => variable_get("site_slogan", "")));
$this->template->parse("header");
print $this->template->text("header");
?>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td colspan="2" id="menu">
<?php
$this->template->assign(array(
"primary" => $this->primary_links,
"secundary" => $this->secundary_links));
$this->template->parse("menu");
print $this->template->text("menu");
?>
</td>
</tr>
<tr>
<td valign="top" width="100%">
<?php
// the description block is only shown on the main page
if (!arg(0)) {
$this->template->assign(array(
"message" => $this->message));
$this->template->parse("message");
print $this->template->text("message");
}
?>
<div id="main">
<?php
}
function box($title, $content, $region = "main") {
if ($title && $content) {
$this->template->assign(array(
"title" => $title,
"content" => $content));
$this->template->parse("block");
print $this->template->text("block");
$this->template->reset("block");
}
}
function footer() {
global $user;
?>
<td valign="top" rowspan="2" id="sidebar">
<?php
theme_blocks("all", $this);
?>
</div>
</td>
</tr>
</table>
<?php
$this->template->parse("footer");
print $this->template->text("footer");
}
}
?>

View File

@ -0,0 +1,70 @@
<!-- BEGIN: header -->
<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>
<!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" lang="en" xml:lang="en">
<head>
<title>{name} - {slogan}</title>
<style type="text/css" media="all">
@import "themes/xtemplate/xtemplate.css";
</style>
</head>
<body>
<!-- END: header -->
<!-- BEGIN: menu -->
<span id="links">
<div id="secundary">{secundary}</div>
<div id="primary">{primary}</div>
</span>
<span id="logo"><a href="index.php"><img src="themes/xtemplate/images/druplicon.gif" alt="" /></a></span>
<!-- END: menu -->
<!-- BEGIN: message -->
<div id="message">{message}</div>
<!-- END: message -->
<!-- BEGIN: node -->
<div id="node">
<div id="title">{title}</div>
<span id="author">Submitted by {author} on {date}.</span>
<span id="taxonomy">{taxonomy}</span>
<div id="content">{content}</div>
<div id="links">&raquo; {links}</div>
</div>
<!-- END: node -->
<!-- BEGIN: comment_new -->
<div id="comment">
<span id="new">new</span>
<div id="title">{title}</div>
<div id="author">Posted by {author} on {date}.</div>
<div id="content">{content}</div>
<div id="links">&raquo; {links}</div>
</div>
<!-- END: comment_new -->
<!-- BEGIN: comment_old -->
<div id="comment">
<div id="title">{title}</div>
<div id="author">Posted by {author} on {date}.</div>
<div id="content">{content}</div>
<div id="links">&raquo; {links}</div>
</div>
<!-- END: comment_old -->
<!-- BEGIN: block -->
<div id="block">
<div id="title">{title}</div>
<div id="content">{content}</div>
</div>
<!-- END: block -->
<!-- BEGIN: footer -->
</body>
</html>
<!-- END: footer -->