虽然分离 HTML 和 Javascript 是一个好主意,但生成一个 Javascript 文件对于实现这一点可能是多余的,而且维护起来也比应有的要困难得多。
我发现最好的方法是向 Smarty 添加简单的插件功能,以允许您生成与在整个站点中多次出现的“小部件”相关的所有 HTML 和 Javascript。
这些插件功能应该:
- 为一个小部件生成所有的 HTML,这样您就不必在不同的 Smarty 模板之间重复 HTML。
- 生成小部件所需的所有 Javascript,这样您就不必在 Smarty 模板中编写 Javascript(这几乎总是一个坏主意——您应该只是调用函数)。
- 将 Javascript 的生成与页面中的实际输出分开,以便您控制 Javascript 的实际放置位置。
向 Smarty 添加功能的 PHP 代码
$GLOBALS['pageJavascript'] = array();
$smarty->registerPlugin("function", "addButton", "addButtonSmarty");
$smarty->registerPlugin("function", "displayPageJavascript", "displayPageJavascript");
//Outputs the HTML for a button, generates the associated Javascript and either
//outputs that Javascript or saves it for later.
function addButtonSmarty($params, &$smarty){
if(isset($params['operation']) == FALSE){
return "operation not set.";
}
if(isset($params['tabID']) == FALSE){
return "tabID not set.";
}
$tabID = $params['tabID']
$operation = $params['operation'];
$uniqueID = "buttonEditOperation_".$operation;
addButtonJavascript($tabID, $operation);
echo "<button id='buttonEditOperation_".$operation."' />";
}
function addButtonJavascript($tabID, $operation){
$javascript = "
$('#tabContent_".$tabID." [id^=\"buttonEditOperation_".$operation."\"]')
.click( function() { alert('CLICK !'); })
.button(blabla);";
if(FALSE){
//You can just add the Javascript directly to the web page, however in this case
//it may throw an error if the user clicks on something before jQuery is
//fully loaded.
echo "<script type="text/javascript">";
echo $javascript;
echo "</script>";
}
else{
//Much better is to save the Javascript to be included later.
$GLOBALS['pageJavascript'][] = $javascript;
}
}
function displayPageJavascript(){
echo "<script type="text/javascript">";
foreach($GLOBALS['pageJavascript'] as $pageJavascript){
echo $pageJavascript;
echo "\n";
}
echo "</script>";
}
无论您在何处添加按钮,而不是直接添加,请执行以下操作:{addButton tabID=$uniqueId operation=$op}
所以你的 Smarty 模板看起来像:
智能模板
<script type="text/javascript" src="./js/buttonInit.js"></script>
<div id="tabContent_{$uniqueId}">
<table>
{foreach $operations as $op}
<tr><td>{addButton tabID=$uniqueId operation=$op}</td></tr>
{/foreach}
</table>
</div>
...
...
...
<!-- bottom of smarty template -->
{displayPageJavascript}
在有人跳进来说用 PHP 编写 HTML 和 Javascript 是丑陋的并且不应该这样做之前 - 我完全同意!
然而在这种情况下,在 Smarty 中将小部件编写为插件的好处超过了丑陋:
- 它使用于操作小部件的 Javascript 位于小部件的 HTML 的几行内,与将它们放在单独的文件中相比,这使得编写和调试该小部件更容易。
- 将小部件的实现从智能模板中隐藏,意味着您可以在一个地方更改它的实现一次,并确保每次使用该小部件都会得到更新。
- 它使代码更加可靠,因为您的模板编辑器不必记住为他们添加的任何小部件单独添加 Javascript,因此编辑模板时的错误将大大减少。