常见误区 - 输出注册资源

  • 作者:KK

  • 发表日期:2016.09.07


速读

如果在模板里执行某某Assets::register($this)或者registerJsFile以及registerCssFile后都没有看到页面上输出script和link标签的话,那你的layout可能写错了,以下代码的layout是不能输出注册的资源的:

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title><?php echo $this->title; ?></title>
</head>
<body>
	<div class="container">
		<?php echo $content; ?>
	</div>
</body>
</html>

必须执行beginPagebeginBody等方法并且最后执行endPage才可以:

<?php $this->beginPage(); ?>
<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title><?php echo $this->title; ?></title>
	<?php $this->head(); ?> //其实这个不是必须的,但正常输出一般都要有
</head>
<body>
	<?php $this->beginBody(); ?>
	<div class="container">
		<?php echo $content; ?>
	</div>
	<?php $this->endBody(); ?>
</body>
</html>
<?php $this->endPage(); ?>

原理

比如执行$this->head()的时候,其实Yii在底层大概是这样echo了一个<![CDATA[YII-BLOCK-HEAD]]>这样的标记,最后将这个标记替换成了注册的资源内容

模板引擎的逻辑大概如下:

public function registerJsFile($js, $position = self::PH_BODY_END){
	if($position == self::PH_BODY_END){
		$this->_bodyEndJs[] = $js; //要输出到底部的
	}else{
		$this->_headJs[] = $js; //要输出到头部的
	}
}

private function renderHeadHtml(){
	//将 $this->_headJs 数组转换成一堆script标签
}

public function renderFile($file, $params){
	ob_start();
	extract($params);
	include($file);
	$模板HTML = ob_get_clean();
	
	//事实上是在endBody方法里实现的,我只是简化逻辑,让大家了解Yii怎么实现注册资源输出而已
	$输出到head的资源HTML = $this->renderHeadHtml();
	$输出到body底部的资源HTML = $this->renderBodyEndHtml();
	
	$模板HTML = str_replace('<![CDATA[YII-BLOCK-HEAD]]>', $输出到head的注册资源HTML);
	$模板HTML = str_replace('<![CDATA[YII-BODY-END]]>', $输出到body底部的资源HTML);
	
	return $模板HTML;
}

renderPartial渲染要注意

这样渲染是不带layout嘛大家都清楚,此时beginPageendPage这些方法神马的记得写到模板里咯,反正没调用这些方法的话甭想输出注册资源