为什么我的 HTML 在使用 Smarty 渲染时格式如此糟糕?
Why is my HTML so poorly formatted when rendered with Smarty?
为什么我的 HTML 查看源代码时格式如此糟糕?
合作对象:
index.php:
<?php
// load required files
require 'class/Slim/Slim.php';
require 'class/RedBean/rb.php';
// register slim auto-loader
\Slim\Slim::registerAutoloader();
// set up database connection
R::setup('mysql:host=localhost;dbname=slimcms','root','');
R::freeze(true);
// initialize app
$app = new \Slim\Slim(array(
'mode' => 'development'
,'debug' => true
,'view' => new \Slim\Views\Smarty()
,'templates.path' => './templates'
));
$view = $app->view();
$view->parserDirectory = dirname(__FILE__) . '/class/Smarty/';
$view->parserCompileDirectory = dirname(__FILE__) . '/compiled';
$view->parserCacheDirectory = dirname(__FILE__) . '/cache';
// handle GET request for index
$app->get('/', function() use ($app){
$books = R::findAll('book');
//print_r($books);
$app->render('home.tpl',array('books'=>$books));
});
$app->run();
templates/home.tpl:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Home</title>
</head>
<body>
<div id="content">
{foreach name=aussen item=book from=$books}
{foreach key=key item=value from=$book}
{if $key == 'id' }
<a href="{$key}/{$value}">{$key}</a>
{else}{$key}{/if}
{/foreach}
<hr />
{/foreach}
</div>
</body>
</html>
当我通过 chrome 查看 源代码时:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Home</title>
</head>
<body>
<div id="content">
<a href="id/1">id</a>
rating price title <hr />
<a href="id/2">id</a>
rating price title <hr />
</div>
</body>
</html>
我会预期:
<!DOCTYPE html>
<html lang="en">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Home</title>
</head>
<body>
<div id="content">
<a href="id/1">id</a> rating price title
<hr>
<a href="id/2">id</a> rating price title
<hr>
</div>
</body>
</html>
目前我找到的解决方案。
=> ~1.1 Dindent
=> ~0.11 tidy,
在 php.ini 中启用扩展=php_tidy.dll
index.php: ~1.1 使用这个:
<?php
// load required files
require 'class/Slim/Slim.php';
require 'class/RedBean/rb.php';
require 'class/Dindent/Indenter.php'; //<= added
// register slim auto-loader
\Slim\Slim::registerAutoloader();
// set up database connection
R::setup('mysql:host=localhost;dbname=slimcms','root','');
R::freeze(true);
// initialize app
$app = new \Slim\Slim(array(
'mode' => 'development'
,'debug' => true
,'view' => new \Slim\Views\Smarty()
,'templates.path' => './templates'
));
$view = $app->view();
$view->parserDirectory = dirname(__FILE__) . '/class/Smarty/';
$view->parserCompileDirectory = dirname(__FILE__) . '/compiled';
$view->parserCacheDirectory = dirname(__FILE__) . '/cache';
// handle GET request for index
$app->get('/', function() use ($app){
$books = R::findAll('book');
//print_r($books);
//$app->render('home.tpl',array('books'=>$books));
$indenter = new \Gajus\Dindent\Indenter(); // <= start added
ob_start(); //
echo $app->render('home.tpl',array('books'=>$books)); //
$content = ob_get_contents(); //
ob_end_clean(); //
echo $indenter->indent($content); // <= end added
});
$app->run();
~0.11 使用这个:
ob_start();
$app->render('home.tpl',array('books'=>$books));
$buffer = ob_get_clean();
$tidy = new tidy();
$clean = $tidy->repairString($buffer,
array(
'indent' => true
,'indent-attributes' => true
));
echo $clean;
按预期输出:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Home</title>
</head>
<body>
<div id="content">
<a href="id/1">id</a> rating price title
<hr />
<a href="id/2">id</a> rating price title
<hr />
</div>
</body>
</html>
既然问的是"why is the code not pretty?"不是"how do I make it pretty?",我就简单回答一下:
Smarty(和 PHP)正好通过您放入模板的空格;它不知道您正在创建的 HTML 结构。唯一会被剥离的是 Smarty 标签本身。
例如,如果你这样写:
[
{if $foo}
foo
{else}
bar
{/if}
]
所有这些空格都将成为输出的一部分,这将是:
[
foo
]
或:
[
bar
]
因此,如果您不希望输出中出现空格,请不要将其包含在输入中。
一个技巧是将其注释掉:
[{*
*}{if $foo}{*
*}foo{*
*}{else}{*
*}bar{*
*}{/if}{*
*}]
这将导致:
[foo]
或:
[bar]
这是对问题 "why" 部分的回答。关于未说出口的 "how to fix" 部分,您最好尝试找出如何生产更小的 HTML,而不是更漂亮的
编译时,Smarty
用 PHP 代码块替换 {
和 }
包含的片段,包含在 <?php
和 ?>
.
以下 Smarty 模板片段:
<div id="content">
{foreach name=aussen item=book from=$books}
{foreach key=key item=value from=$book}
{if $key == 'id' }
<a href="{$key}/{$value}">{$key}</a>
{else}{$key}{/if}
{/foreach}
<hr />
{/foreach}
</div>
变成类似:
<div id="content">
<?php foreach ($books as $book): ?>
<?php foreach ($book as $key => $value) : ?>
<?php if ($key == 'id'): ?>
<a href="<?php echo $key; ?>/<?php echo $value; ?>">{$key}</a>
<?php else ?><?php echo $key; ?><?php endif; ?>
<?php endforeach; ?>
<hr />
<?php endforeach; ?>
</div>
请注意,上面的 PHP 代码不是 Smarty 生成的。由于 Smarty 存储分配给模板的变量的方式、处理内置函数属性的方式、变量修饰符以及它提供的其他功能,Smarty 生成的代码更加复杂。
但出于本次讨论的目的,这个过于简化的代码版本就足够了。这里重要的是 Smarty
不会更改 { ... }
块之外的任何内容。
Smarty
不会破坏 template/HTML 代码的格式。 PHP
就是这样做的。
PHP
解释代码块(包含在 <?php
和 ?>
中)并将它们替换为它们生成的输出(如果有)。但如果换行符紧跟在 PHP 结束标记 ?>
.
之后,它也会删除换行符
The closing tag for the block will include the immediately trailing newline if one is present.
(来源:http://php.net/manual/en/language.basic-syntax.instruction-separation.php)
但是,Smarty
和 PHP
都没有删除用于 Smarty 标签缩进的空格(因为它们不在标签内)。他们进入了决赛 HTML,由于删除了换行符,他们破坏了格式。
为什么我的 HTML 查看源代码时格式如此糟糕?
合作对象:
index.php:
<?php
// load required files
require 'class/Slim/Slim.php';
require 'class/RedBean/rb.php';
// register slim auto-loader
\Slim\Slim::registerAutoloader();
// set up database connection
R::setup('mysql:host=localhost;dbname=slimcms','root','');
R::freeze(true);
// initialize app
$app = new \Slim\Slim(array(
'mode' => 'development'
,'debug' => true
,'view' => new \Slim\Views\Smarty()
,'templates.path' => './templates'
));
$view = $app->view();
$view->parserDirectory = dirname(__FILE__) . '/class/Smarty/';
$view->parserCompileDirectory = dirname(__FILE__) . '/compiled';
$view->parserCacheDirectory = dirname(__FILE__) . '/cache';
// handle GET request for index
$app->get('/', function() use ($app){
$books = R::findAll('book');
//print_r($books);
$app->render('home.tpl',array('books'=>$books));
});
$app->run();
templates/home.tpl:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Home</title>
</head>
<body>
<div id="content">
{foreach name=aussen item=book from=$books}
{foreach key=key item=value from=$book}
{if $key == 'id' }
<a href="{$key}/{$value}">{$key}</a>
{else}{$key}{/if}
{/foreach}
<hr />
{/foreach}
</div>
</body>
</html>
当我通过 chrome 查看 源代码时:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Home</title>
</head>
<body>
<div id="content">
<a href="id/1">id</a>
rating price title <hr />
<a href="id/2">id</a>
rating price title <hr />
</div>
</body>
</html>
我会预期:
<!DOCTYPE html>
<html lang="en">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Home</title>
</head>
<body>
<div id="content">
<a href="id/1">id</a> rating price title
<hr>
<a href="id/2">id</a> rating price title
<hr>
</div>
</body>
</html>
目前我找到的解决方案。
=> ~1.1 Dindent
=> ~0.11 tidy,
在 php.ini 中启用扩展=php_tidy.dll
index.php: ~1.1 使用这个:
<?php
// load required files
require 'class/Slim/Slim.php';
require 'class/RedBean/rb.php';
require 'class/Dindent/Indenter.php'; //<= added
// register slim auto-loader
\Slim\Slim::registerAutoloader();
// set up database connection
R::setup('mysql:host=localhost;dbname=slimcms','root','');
R::freeze(true);
// initialize app
$app = new \Slim\Slim(array(
'mode' => 'development'
,'debug' => true
,'view' => new \Slim\Views\Smarty()
,'templates.path' => './templates'
));
$view = $app->view();
$view->parserDirectory = dirname(__FILE__) . '/class/Smarty/';
$view->parserCompileDirectory = dirname(__FILE__) . '/compiled';
$view->parserCacheDirectory = dirname(__FILE__) . '/cache';
// handle GET request for index
$app->get('/', function() use ($app){
$books = R::findAll('book');
//print_r($books);
//$app->render('home.tpl',array('books'=>$books));
$indenter = new \Gajus\Dindent\Indenter(); // <= start added
ob_start(); //
echo $app->render('home.tpl',array('books'=>$books)); //
$content = ob_get_contents(); //
ob_end_clean(); //
echo $indenter->indent($content); // <= end added
});
$app->run();
~0.11 使用这个:
ob_start();
$app->render('home.tpl',array('books'=>$books));
$buffer = ob_get_clean();
$tidy = new tidy();
$clean = $tidy->repairString($buffer,
array(
'indent' => true
,'indent-attributes' => true
));
echo $clean;
按预期输出:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Home</title>
</head>
<body>
<div id="content">
<a href="id/1">id</a> rating price title
<hr />
<a href="id/2">id</a> rating price title
<hr />
</div>
</body>
</html>
既然问的是"why is the code not pretty?"不是"how do I make it pretty?",我就简单回答一下:
Smarty(和 PHP)正好通过您放入模板的空格;它不知道您正在创建的 HTML 结构。唯一会被剥离的是 Smarty 标签本身。
例如,如果你这样写:
[
{if $foo}
foo
{else}
bar
{/if}
]
所有这些空格都将成为输出的一部分,这将是:
[
foo
]
或:
[
bar
]
因此,如果您不希望输出中出现空格,请不要将其包含在输入中。
一个技巧是将其注释掉:
[{*
*}{if $foo}{*
*}foo{*
*}{else}{*
*}bar{*
*}{/if}{*
*}]
这将导致:
[foo]
或:
[bar]
这是对问题 "why" 部分的回答。关于未说出口的 "how to fix" 部分,您最好尝试找出如何生产更小的 HTML,而不是更漂亮的
编译时,Smarty
用 PHP 代码块替换 {
和 }
包含的片段,包含在 <?php
和 ?>
.
以下 Smarty 模板片段:
<div id="content">
{foreach name=aussen item=book from=$books}
{foreach key=key item=value from=$book}
{if $key == 'id' }
<a href="{$key}/{$value}">{$key}</a>
{else}{$key}{/if}
{/foreach}
<hr />
{/foreach}
</div>
变成类似:
<div id="content">
<?php foreach ($books as $book): ?>
<?php foreach ($book as $key => $value) : ?>
<?php if ($key == 'id'): ?>
<a href="<?php echo $key; ?>/<?php echo $value; ?>">{$key}</a>
<?php else ?><?php echo $key; ?><?php endif; ?>
<?php endforeach; ?>
<hr />
<?php endforeach; ?>
</div>
请注意,上面的 PHP 代码不是 Smarty 生成的。由于 Smarty 存储分配给模板的变量的方式、处理内置函数属性的方式、变量修饰符以及它提供的其他功能,Smarty 生成的代码更加复杂。
但出于本次讨论的目的,这个过于简化的代码版本就足够了。这里重要的是 Smarty
不会更改 { ... }
块之外的任何内容。
Smarty
不会破坏 template/HTML 代码的格式。 PHP
就是这样做的。
PHP
解释代码块(包含在 <?php
和 ?>
中)并将它们替换为它们生成的输出(如果有)。但如果换行符紧跟在 PHP 结束标记 ?>
.
The closing tag for the block will include the immediately trailing newline if one is present.
(来源:http://php.net/manual/en/language.basic-syntax.instruction-separation.php)
但是,Smarty
和 PHP
都没有删除用于 Smarty 标签缩进的空格(因为它们不在标签内)。他们进入了决赛 HTML,由于删除了换行符,他们破坏了格式。