summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxue <>2006-01-29 09:14:14 +0000
committerxue <>2006-01-29 09:14:14 +0000
commit976e3aa06ebe82fe6d1c7317c827425111be5df6 (patch)
tree7ca22e6681cd1203a70acb4710c1ee3cfa2bc337
parent80c39c977568b5b84f5ea2b93f8c1e8d799d558a (diff)
Added support to template tag.
-rw-r--r--framework/Exceptions/messages.txt1
-rw-r--r--framework/Web/Services/TPageService.php11
-rw-r--r--framework/Web/UI/TPage.php15
-rw-r--r--framework/Web/UI/TTemplateManager.php79
4 files changed, 62 insertions, 44 deletions
diff --git a/framework/Exceptions/messages.txt b/framework/Exceptions/messages.txt
index 55c2f112..602efcdd 100644
--- a/framework/Exceptions/messages.txt
+++ b/framework/Exceptions/messages.txt
@@ -106,6 +106,7 @@ template_databind_forbidden = %s is a non-control component. No databinding e
template_component_required = '%s' is not a component. Only components can appear in a template.
template_format_invalid = Error in %s (line %d) : %s
template_format_invalid2 = Error at line %d of the following template: %s %s
+template_eventhandler_invalid = An invalid event handler is attached to %s's event '%s'.
xmldocument_file_read_failed = TXmlDocument is unable to read file '%s'.
xmldocument_file_write_failed = TXmlDocument is unable to write file '%s'.
diff --git a/framework/Web/Services/TPageService.php b/framework/Web/Services/TPageService.php
index 0d8f28b9..239cf870 100644
--- a/framework/Web/Services/TPageService.php
+++ b/framework/Web/Services/TPageService.php
@@ -442,10 +442,15 @@ class TPageService extends TService
}
else
$className='TPage';
- //allow the page constructor to change application settings before template is loaded
+
$this->_page=new $className();
- $this->_properties['Template']=$this->getTemplateManager()->getTemplateByFileName($path.self::PAGE_FILE_EXT);
- $this->_page->initializeProperties($this->_properties);
+
+ // initialize page properties with those set in configurations
+ foreach($this->_properties as $name=>$value)
+ $this->_page->setSubProperty($name,$value);
+
+ // set page template
+ $this->_page->setTemplate($this->getTemplateManager()->getTemplateByFileName($path.self::PAGE_FILE_EXT));
}
else
throw new THttpException(404,'pageservice_page_unknown',$this->_pagePath);
diff --git a/framework/Web/UI/TPage.php b/framework/Web/UI/TPage.php
index a5e4fa52..b7c1bae6 100644
--- a/framework/Web/UI/TPage.php
+++ b/framework/Web/UI/TPage.php
@@ -121,21 +121,6 @@ class TPage extends TTemplateControl
}
/**
- * If initial property values are given, they will be set to the page.
- * @param array initial property values for the page.
- */
- public function initializeProperties($initProperties=null)
- {
- Prado::trace('Constructing page','System.Web.UI.TPage');
- if(is_array($initProperties))
- {
- Prado::trace('Initializing page properties specified in configurations','System.Web.UI.TPage');
- foreach($initProperties as $name=>$value)
- $this->setSubProperty($name,$value);
- }
- }
-
- /**
* Runs through the page lifecycles.
* This method runs through the page lifecycles.
* @param THtmlTextWriter the HTML writer
diff --git a/framework/Web/UI/TTemplateManager.php b/framework/Web/UI/TTemplateManager.php
index 312b821d..8ca95b33 100644
--- a/framework/Web/UI/TTemplateManager.php
+++ b/framework/Web/UI/TTemplateManager.php
@@ -70,7 +70,7 @@ class TTemplateManager extends TModule
*/
public function getTemplateByFileName($fileName)
{
- if(!is_null($fileName=$this->getLocalizedTemplate($fileName)))
+ if(($fileName=$this->getLocalizedTemplate($fileName))!==null)
{
Prado::trace("Loading template $fileName",'System.Web.UI.TTemplateManager');
if(($cache=$this->getApplication()->getCache())===null)
@@ -107,7 +107,7 @@ class TTemplateManager extends TModule
if(($file=realpath($file))!==false && is_file($file))
return $file;
}
-
+ return null;
}
}
@@ -164,6 +164,7 @@ class TTemplate extends TComponent implements ITemplate
const CONFIG_ASSET=2;
const CONFIG_PARAMETER=3;
const CONFIG_LOCALIZATION=4;
+ const CONFIG_TEMPLATE=5;
/**
* @var array list of component tags and strings
@@ -185,6 +186,14 @@ class TTemplate extends TComponent implements ITemplate
* @var TAssetManager asset manager
*/
private $_assetManager;
+ /**
+ * @var integer the line number that parsing starts from (internal use)
+ */
+ private $_startingLine=0;
+ /**
+ * @var string template content to be parsed
+ */
+ private $_content;
/**
@@ -193,12 +202,16 @@ class TTemplate extends TComponent implements ITemplate
* @param string the template string
* @param string the template context directory
* @param string the template file, null if no file
+ * @param integer the line number that parsing starts from (internal use)
*/
- public function __construct($template,$contextPath,$tplFile=null)
+ public function __construct($template,$contextPath,$tplFile=null,$startingLine=0)
{
$this->_contextPath=$contextPath;
$this->_tplFile=$tplFile;
+ $this->_startingLine=$startingLine;
+ $this->_content=$template;
$this->parse($template);
+ $this->_content=null; // reset to save memory
}
/**
@@ -292,7 +305,7 @@ class TTemplate extends TComponent implements ITemplate
*/
protected function configureControl($control,$name,$value)
{
- if(is_string($value) && strncasecmp($name,'on',2)===0) // is an event
+ if(strncasecmp($name,'on',2)===0) // is an event
$this->configureEvent($control,$name,$value);
else if(strpos($name,'.')===false) // is a simple property or custom attribute
$this->configureProperty($control,$name,$value);
@@ -347,6 +360,9 @@ class TTemplate extends TComponent implements ITemplate
case self::CONFIG_EXPRESSION:
$component->$setter($component->evaluateExpression($value[1]));
break;
+ case self::CONFIG_TEMPLATE:
+ $component->$setter($value[1]);
+ break;
case self::CONFIG_ASSET: // asset URL
$url=$this->_assetManager->publishFilePath($this->_contextPath.'/'.$value[1]);
$component->$setter($url);
@@ -384,6 +400,9 @@ class TTemplate extends TComponent implements ITemplate
case self::CONFIG_EXPRESSION: // expression
$component->setSubProperty($name,$component->evaluateExpression($value[1]));
break;
+ case self::CONFIG_TEMPLATE:
+ $component->setSubProperty($name,$value[1]);
+ break;
case self::CONFIG_ASSET: // asset URL
$url=$this->_assetManager->publishFilePath($this->_contextPath.'/'.$value[1]);
$component->setSubProperty($name,$url);
@@ -449,7 +468,7 @@ class TTemplate extends TComponent implements ITemplate
$tpl[$c++]=array($container,substr($input,$textStart,$matchStart-$textStart));
$textStart=$matchEnd+1;
$type=$match[1][0];
- $attributes=$this->parseAttributes($match[2][0]);
+ $attributes=$this->parseAttributes($match[2][0],$match[2][1]);
$this->validateAttributes($type,$attributes);
$tpl[$c++]=array($container,$type,$attributes);
if($str[strlen($str)-2]!=='/') // open tag
@@ -487,7 +506,7 @@ class TTemplate extends TComponent implements ITemplate
$textStart=$matchEnd+1;
if(isset($tpl[0]))
throw new TConfigurationException('template_directive_nonunique');
- $this->_directive=$this->parseAttributes($match[4][0]);
+ $this->_directive=$this->parseAttributes($match[4][0],$match[4][1]);
}
else if(strpos($str,'<%')===0) // expression
{
@@ -501,7 +520,7 @@ class TTemplate extends TComponent implements ITemplate
else if($str[2]==='%') // statements
$tpl[$c++]=array($container,'TStatements',array('Statements'=>THttpUtility::htmlDecode($match[5][0])));
else
- $tpl[$c++]=array($container,'TLiteral',array('Text'=>$this->parseAttribute($str)));
+ $tpl[$c++]=array($container,'TLiteral',array('Text'=>$this->parseAttribute($str,$matchStart)));
}
else if(strpos($str,'<prop:')===0) // opening property
{
@@ -519,13 +538,7 @@ class TTemplate extends TComponent implements ITemplate
{
$prop=strtolower($match[3][0]);
if(empty($stack))
- {
- $line=count(explode("\n",substr($input,0,$matchEnd+1)));
- if($this->_tplFile===null)
- throw new TConfigurationException('template_closingtag_unexpected',"Line $line","</prop:$prop>");
- else
- throw new TConfigurationException('template_closingtag_unexpected',"{$this->_tplFile} (Line $line)","</prop:$prop>");
- }
+ throw new TConfigurationException('template_closingtag_unexpected',"</prop:$prop>");
$name=array_pop($stack);
if($name!=='@'.$prop)
{
@@ -537,7 +550,7 @@ class TTemplate extends TComponent implements ITemplate
if($matchStart>$textStart && $container>=0)
{
$value=substr($input,$textStart,$matchStart-$textStart);
- $value=$this->parseAttribute($value);
+ $value=$this->parseAttribute($value,$textStart);
$type=$tpl[$container][1];
$this->validateAttributes($type,array($prop=>$value));
$tpl[$container][2][$prop]=$value;
@@ -572,10 +585,12 @@ class TTemplate extends TComponent implements ITemplate
}
catch(Exception $e)
{
+ if($e->getErrorCode()==='template_format_invalid' || $e->getErrorCode()==='template_format_invalid2')
+ throw $e;
if($matchEnd===0)
- $line=1;
+ $line=$this->_startingLine+1;
else
- $line=count(explode("\n",substr($input,0,$matchEnd+1)));
+ $line=$this->_startingLine+count(explode("\n",substr($input,0,$matchEnd+1)));
if(empty($this->_tplFile))
throw new TConfigurationException('template_format_invalid2',$line,$e->getMessage(),$input);
else
@@ -589,20 +604,22 @@ class TTemplate extends TComponent implements ITemplate
* @param string the string to be parsed.
* @return array attribute values indexed by names.
*/
- protected function parseAttributes($str)
+ protected function parseAttributes($str,$offset)
{
if($str==='')
return array();
$pattern='/([\w\.]+)=(\'.*?\'|".*?"|<%.*?%>)/msS';
$attributes=array();
- $n=preg_match_all($pattern,$str,$matches,PREG_SET_ORDER);
+ $n=preg_match_all($pattern,$str,$matches,PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
for($i=0;$i<$n;++$i)
{
- $name=strtolower($matches[$i][1]);
- $value=$matches[$i][2];
+ $match=&$matches[$i];
+ $name=strtolower($match[1][0]);
+ $value=$match[2][0];
if($value[0]==='\'' || $value[0]==='"')
- $value=substr($value,1,strlen($value)-2);
- $attributes[$name]=$this->parseAttribute($value);
+ $attributes[$name]=$this->parseAttribute(substr($value,1,strlen($value)-2),$match[2][1]+1);
+ else
+ $attributes[$name]=$this->parseAttribute($value,$match[2][1]);
}
return $attributes;
}
@@ -612,12 +629,20 @@ class TTemplate extends TComponent implements ITemplate
* @param string the string to be parsed.
* @return array attribute initialization
*/
- protected function parseAttribute($value)
+ protected function parseAttribute($value,$offset)
{
$matches=array();
- if(!preg_match('/^(<%#.*?%>|<%=.*?%>|<%~.*?%>|<%\\$.*?%>|<%\\[.*?\\]%>)$/msS',$value,$matches))
+ if(!preg_match('/\\s*(<%!.*?%>|<%#.*?%>|<%=.*?%>|<%~.*?%>|<%\\$.*?%>|<%\\[.*?\\]%>)\\s*/msS',$value,$matches) || $matches[0]!==$value)
return THttpUtility::htmlDecode($value);
- $value=THttpUtility::htmlDecode($matches[1]);
+ $match=$matches[1];
+ if($match[2]==='!')
+ {
+ $offset+=strpos($value,$match);
+ $line=$this->_startingLine+count(explode("\n",substr($this->_content,0,$offset)))-1;
+ $content=substr($match,3,strlen($match)-5);
+ return array(self::CONFIG_TEMPLATE,new TTemplate($content,$this->_contextPath,$this->_tplFile,$line));
+ }
+ $value=THttpUtility::htmlDecode($match);
if($value[2]==='#') // databind
return array(self::CONFIG_DATABIND,substr($value,3,strlen($value)-5));
else if($value[2]==='=') // a dynamic initialization
@@ -653,6 +678,8 @@ class TTemplate extends TComponent implements ITemplate
// an event
if(!is_callable(array($className,$name)))
throw new TConfigurationException('template_event_unknown',$type,$name);
+ else if(!is_string($att))
+ throw new TConfigurationException('template_eventhandler_invalid',$type,$name);
}
else
{